Create basic interactive physics system
This commit is contained in:
parent
6108f140b6
commit
6732f5575c
3 changed files with 190 additions and 129 deletions
91
Cargo.lock
generated
91
Cargo.lock
generated
|
@ -85,7 +85,7 @@ checksum = "e89da841a80418a9b391ebaea17f5c112ffaaa96f621d2c285b5174da76b9011"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"const-random",
|
"const-random",
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"version_check",
|
"version_check",
|
||||||
"zerocopy 0.7.35",
|
"zerocopy 0.7.35",
|
||||||
|
@ -718,7 +718,7 @@ dependencies = [
|
||||||
"derive_more",
|
"derive_more",
|
||||||
"glam",
|
"glam",
|
||||||
"itertools",
|
"itertools",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"rand_distr",
|
"rand_distr",
|
||||||
"serde",
|
"serde",
|
||||||
"smallvec",
|
"smallvec",
|
||||||
|
@ -1051,7 +1051,7 @@ checksum = "63c2174d43a0de99f863c98a472370047a2bfa7d1e5cec8d9d647fb500905d9d"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ahash",
|
"ahash",
|
||||||
"bevy_utils_proc_macros",
|
"bevy_utils_proc_macros",
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
"hashbrown 0.14.5",
|
"hashbrown 0.14.5",
|
||||||
"thread_local",
|
"thread_local",
|
||||||
"tracing",
|
"tracing",
|
||||||
|
@ -1409,7 +1409,7 @@ version = "0.1.16"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
|
checksum = "f9d839f2a20b0aee515dc581a6172f2321f96cab76c1a38a4c584a194955390e"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
"once_cell",
|
"once_cell",
|
||||||
"tiny-keccak",
|
"tiny-keccak",
|
||||||
]
|
]
|
||||||
|
@ -1606,6 +1606,7 @@ dependencies = [
|
||||||
"avian2d",
|
"avian2d",
|
||||||
"bevy",
|
"bevy",
|
||||||
"log",
|
"log",
|
||||||
|
"rand 0.9.0",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1882,10 +1883,22 @@ dependencies = [
|
||||||
"cfg-if",
|
"cfg-if",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
"libc",
|
"libc",
|
||||||
"wasi",
|
"wasi 0.11.0+wasi-snapshot-preview1",
|
||||||
"wasm-bindgen",
|
"wasm-bindgen",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "getrandom"
|
||||||
|
version = "0.3.2"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "73fea8450eea4bac3940448fb7ae50d91f034f941199fcd9d909a5a07aa455f0"
|
||||||
|
dependencies = [
|
||||||
|
"cfg-if",
|
||||||
|
"libc",
|
||||||
|
"r-efi",
|
||||||
|
"wasi 0.14.2+wasi-0.2.4",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gl_generator"
|
name = "gl_generator"
|
||||||
version = "0.14.0"
|
version = "0.14.0"
|
||||||
|
@ -1904,7 +1917,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677"
|
checksum = "dc46dd3ec48fdd8e693a98d2b8bafae273a2d54c1de02a2a7e3d57d501f39677"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"bytemuck",
|
"bytemuck",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3036,6 +3049,12 @@ dependencies = [
|
||||||
"proc-macro2",
|
"proc-macro2",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "r-efi"
|
||||||
|
version = "5.2.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "radsort"
|
name = "radsort"
|
||||||
version = "0.1.1"
|
version = "0.1.1"
|
||||||
|
@ -3049,8 +3068,19 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
checksum = "34af8d1a0e25924bc5b7c43c079c942339d8f0a8b57c39049bef581b46327404"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"libc",
|
"libc",
|
||||||
"rand_chacha",
|
"rand_chacha 0.3.1",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "3779b94aeb87e8bd4e834cee3650289ee9e0d5677f976ecdb6d219e5f4f6cd94"
|
||||||
|
dependencies = [
|
||||||
|
"rand_chacha 0.9.0",
|
||||||
|
"rand_core 0.9.3",
|
||||||
|
"zerocopy 0.8.24",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3060,7 +3090,17 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
checksum = "e6c10a63a0fa32252be49d21e7709d4d4baf8d231c2dbce1eaa8141b9b127d88"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"ppv-lite86",
|
"ppv-lite86",
|
||||||
"rand_core",
|
"rand_core 0.6.4",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_chacha"
|
||||||
|
version = "0.9.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "d3022b5f1df60f26e1ffddd6c66e8aa15de382ae63b3a0c1bfc0e4d3e3f325cb"
|
||||||
|
dependencies = [
|
||||||
|
"ppv-lite86",
|
||||||
|
"rand_core 0.9.3",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3069,7 +3109,16 @@ version = "0.6.4"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
checksum = "ec0be4795e2f6a28069bec0b5ff3e2ac9bafc99e6a9a7dc3547996c5c816922c"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "rand_core"
|
||||||
|
version = "0.9.3"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "99d9a13982dcf210057a8a78572b2217b667c3beacbf3a0d8b454f6f82837d38"
|
||||||
|
dependencies = [
|
||||||
|
"getrandom 0.3.2",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3079,7 +3128,7 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
|
checksum = "32cb0b9bc82b0a0876c2dd994a7e7a2683d3e7390ca40e6886785ef0c7e3ee31"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"num-traits",
|
"num-traits",
|
||||||
"rand",
|
"rand 0.8.5",
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -3833,7 +3882,7 @@ version = "1.12.1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
|
checksum = "b3758f5e68192bb96cc8f9b7e2c2cfdabb435499a28499a42f8f984092adad4b"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"getrandom",
|
"getrandom 0.2.15",
|
||||||
"serde",
|
"serde",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
@ -3865,6 +3914,15 @@ version = "0.11.0+wasi-snapshot-preview1"
|
||||||
source = "registry+https://github.com/rust-lang/crates.io-index"
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
checksum = "9c8d87e72b64a3b4db28d11ce29237c246188f4f51057d65a7eab63b7987e423"
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wasi"
|
||||||
|
version = "0.14.2+wasi-0.2.4"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "9683f9a5a998d873c0d21fcbe3c083009670149a8fab228644b8bd36b2c48cb3"
|
||||||
|
dependencies = [
|
||||||
|
"wit-bindgen-rt",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "wasm-bindgen"
|
name = "wasm-bindgen"
|
||||||
version = "0.2.100"
|
version = "0.2.100"
|
||||||
|
@ -4480,6 +4538,15 @@ dependencies = [
|
||||||
"memchr",
|
"memchr",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
[[package]]
|
||||||
|
name = "wit-bindgen-rt"
|
||||||
|
version = "0.39.0"
|
||||||
|
source = "registry+https://github.com/rust-lang/crates.io-index"
|
||||||
|
checksum = "6f42320e61fe2cfd34354ecb597f86f413484a798ba44a8ca1165c58d42da6c1"
|
||||||
|
dependencies = [
|
||||||
|
"bitflags 2.9.0",
|
||||||
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "xcursor"
|
name = "xcursor"
|
||||||
version = "0.3.8"
|
version = "0.3.8"
|
||||||
|
|
|
@ -33,3 +33,4 @@ log = { version = "*", features = [
|
||||||
"max_level_debug",
|
"max_level_debug",
|
||||||
"release_max_level_warn",
|
"release_max_level_warn",
|
||||||
] }
|
] }
|
||||||
|
rand = "0.9.0"
|
||||||
|
|
217
src/main.rs
217
src/main.rs
|
@ -1,152 +1,145 @@
|
||||||
//! This example showcases how `Transform` interpolation or extrapolation can be used
|
use std::f32::consts::PI;
|
||||||
//! to make movement appear smooth at fixed timesteps.
|
|
||||||
//!
|
|
||||||
//! To produce consistent, frame rate independent behavior, physics by default runs
|
|
||||||
//! in the `FixedPostUpdate` schedule with a fixed timestep, meaning that the time between
|
|
||||||
//! physics ticks remains constant. On some frames, physics can either not run at all or run
|
|
||||||
//! more than once to catch up to real time. This can lead to visible stutter for movement.
|
|
||||||
//!
|
|
||||||
//! `Transform` interpolation resolves this issue by updating `Transform` at every frame in between
|
|
||||||
//! physics ticks to smooth out the visual result. The interpolation is done from the previous position
|
|
||||||
//! to the current physics position, which keeps movement smooth, but has the downside of making movement
|
|
||||||
//! feel slightly delayed as the rendered result lags slightly behind the true positions.
|
|
||||||
//!
|
|
||||||
//! `Transform` extrapolation works similarly, but instead of using the previous positions, it predicts
|
|
||||||
//! the next positions based on velocity. This makes movement feel much more responsive, but can cause
|
|
||||||
//! jumpy results when the prediction is wrong, such as when the velocity of an object is suddenly altered.
|
|
||||||
|
|
||||||
use avian2d::{math::*, prelude::*};
|
use avian2d::{math::Vector, prelude::*};
|
||||||
use bevy::{
|
use bevy::{
|
||||||
color::palettes::{
|
color::palettes::{
|
||||||
css::WHITE,
|
css::WHITE,
|
||||||
tailwind::{CYAN_400, LIME_400, RED_400},
|
tailwind::{LIME_400, RED_400},
|
||||||
},
|
},
|
||||||
input::common_conditions::input_pressed,
|
input::common_conditions::input_pressed,
|
||||||
prelude::*,
|
prelude::*,
|
||||||
};
|
};
|
||||||
|
use rand::Rng;
|
||||||
|
|
||||||
|
const AREA_WIDTH: f32 = 750.;
|
||||||
|
const PLAYER_SIZE: f32 = 30.;
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
let mut app = App::new();
|
App::new()
|
||||||
|
.add_plugins((
|
||||||
// Interpolation and extrapolation functionality is enabled by the `PhysicsInterpolationPlugin`.
|
|
||||||
// It is included in the `PhysicsPlugins` by default.
|
|
||||||
app.add_plugins((
|
|
||||||
DefaultPlugins,
|
DefaultPlugins,
|
||||||
PhysicsPlugins::default().with_length_unit(50.0),
|
PhysicsPlugins::default()
|
||||||
));
|
.with_length_unit(50.0)
|
||||||
|
.set(PhysicsInterpolationPlugin::interpolate_all()),
|
||||||
// By default, interpolation must be enabled for each entity manually
|
))
|
||||||
// by adding the `TransformInterpolation` component.
|
.add_systems(
|
||||||
//
|
Startup,
|
||||||
// It can also be enabled for all rigid bodies with `PhysicsInterpolationPlugin::interpolate_all()`:
|
(setup_scene, setup_player, setup_balls, setup_walls),
|
||||||
//
|
)
|
||||||
// app.add_plugins(PhysicsPlugins::default().set(PhysicsInterpolationPlugin::interpolate_all()));
|
|
||||||
|
|
||||||
// Set gravity.
|
|
||||||
app.insert_resource(Gravity(Vector::NEG_Y * 900.0));
|
|
||||||
|
|
||||||
// Set the fixed timestep to just 10 Hz for demonstration purposes.
|
|
||||||
app.insert_resource(Time::from_hz(10.0));
|
|
||||||
|
|
||||||
// Setup the scene and UI, and update text in `Update`.
|
|
||||||
app.add_systems(Startup, (setup_scene, setup_balls))
|
|
||||||
.add_systems(
|
.add_systems(
|
||||||
Update,
|
Update,
|
||||||
(
|
(move_player, quit.run_if(input_pressed(KeyCode::KeyQ))),
|
||||||
change_timestep,
|
)
|
||||||
// Reset the scene when the 'R' key is pressed.
|
.insert_resource(Gravity(Vector::ZERO))
|
||||||
reset_balls.run_if(input_pressed(KeyCode::KeyR)),
|
.run();
|
||||||
),
|
|
||||||
);
|
|
||||||
|
|
||||||
// Run the app.
|
|
||||||
app.run();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Component)]
|
fn setup_scene(mut commands: Commands) {
|
||||||
struct Ball;
|
|
||||||
|
|
||||||
fn setup_scene(
|
|
||||||
mut commands: Commands,
|
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
|
||||||
) {
|
|
||||||
// Spawn a camera.
|
|
||||||
commands.spawn(Camera2d);
|
commands.spawn(Camera2d);
|
||||||
|
|
||||||
// Spawn the ground.
|
|
||||||
commands.spawn((
|
|
||||||
Name::new("Ground"),
|
|
||||||
RigidBody::Static,
|
|
||||||
Collider::rectangle(500.0, 20.0),
|
|
||||||
Restitution::new(0.99).with_combine_rule(CoefficientCombine::Max),
|
|
||||||
Transform::from_xyz(0.0, -300.0, 0.0),
|
|
||||||
Mesh2d(meshes.add(Rectangle::new(500.0, 20.0))),
|
|
||||||
MeshMaterial2d(materials.add(Color::from(WHITE))),
|
|
||||||
));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
#[require(Collider, Mesh2d, MeshMaterial2d<ColorMaterial>, Restitution(|| Restitution::new(1.0)), RigidBody, TransformInterpolation, Transform)]
|
||||||
|
struct GameObject;
|
||||||
|
|
||||||
|
#[derive(Component, Default)]
|
||||||
|
#[require(GameObject, RigidBody(|| RigidBody::Dynamic))]
|
||||||
|
struct Ball;
|
||||||
|
|
||||||
fn setup_balls(
|
fn setup_balls(
|
||||||
mut commands: Commands,
|
mut commands: Commands,
|
||||||
mut materials: ResMut<Assets<ColorMaterial>>,
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
mut meshes: ResMut<Assets<Mesh>>,
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
) {
|
) {
|
||||||
let circle = Circle::new(30.0);
|
let mut rng = rand::rng();
|
||||||
let mesh = meshes.add(circle);
|
for _ in 0..20 {
|
||||||
|
let circle = Circle::new(rng.random_range(10.0..(PLAYER_SIZE - 5.)));
|
||||||
// This entity uses transform interpolation.
|
let mut transform = Transform::from_xyz(
|
||||||
|
0.,
|
||||||
|
rng.random_range((PLAYER_SIZE + 5.)..(AREA_WIDTH / 2. - PLAYER_SIZE)),
|
||||||
|
0.,
|
||||||
|
);
|
||||||
|
transform.rotate_around(
|
||||||
|
Vec3::ZERO,
|
||||||
|
Quat::from_rotation_z(rng.random_range(0.0..(PI * 2.))),
|
||||||
|
);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Name::new("Interpolation"),
|
|
||||||
Ball,
|
Ball,
|
||||||
RigidBody::Dynamic,
|
|
||||||
Collider::from(circle),
|
Collider::from(circle),
|
||||||
TransformInterpolation,
|
Mesh2d(meshes.add(circle)),
|
||||||
Transform::from_xyz(-100.0, 300.0, 0.0),
|
MeshMaterial2d(materials.add(Color::from(RED_400))),
|
||||||
Mesh2d(mesh.clone()),
|
transform,
|
||||||
MeshMaterial2d(materials.add(Color::from(CYAN_400)).clone()),
|
|
||||||
));
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This entity uses transform extrapolation.
|
#[derive(Component, Default)]
|
||||||
commands.spawn((
|
#[require(Ball, RigidBody(|| RigidBody::Dynamic))]
|
||||||
Name::new("Extrapolation"),
|
struct Player;
|
||||||
Ball,
|
|
||||||
RigidBody::Dynamic,
|
|
||||||
Collider::from(circle),
|
|
||||||
TransformExtrapolation,
|
|
||||||
Transform::from_xyz(0.0, 300.0, 0.0),
|
|
||||||
Mesh2d(mesh.clone()),
|
|
||||||
MeshMaterial2d(materials.add(Color::from(LIME_400)).clone()),
|
|
||||||
));
|
|
||||||
|
|
||||||
// This entity is simulated in `FixedUpdate` without any smoothing.
|
fn setup_player(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
) {
|
||||||
|
let circle = Circle::new(PLAYER_SIZE);
|
||||||
commands.spawn((
|
commands.spawn((
|
||||||
Name::new("No Interpolation"),
|
Player,
|
||||||
Ball,
|
|
||||||
RigidBody::Dynamic,
|
|
||||||
Collider::from(circle),
|
Collider::from(circle),
|
||||||
Transform::from_xyz(100.0, 300.0, 0.0),
|
Mesh2d(meshes.add(circle)),
|
||||||
Mesh2d(mesh.clone()),
|
MeshMaterial2d(materials.add(Color::from(LIME_400))),
|
||||||
MeshMaterial2d(materials.add(Color::from(RED_400)).clone()),
|
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Despawns all balls and respawns them.
|
#[derive(Component, Default)]
|
||||||
fn reset_balls(mut commands: Commands, query: Query<Entity, With<Ball>>) {
|
#[require(GameObject, RigidBody(|| RigidBody::Static))]
|
||||||
for entity in &query {
|
struct Wall;
|
||||||
commands.entity(entity).despawn();
|
|
||||||
}
|
|
||||||
|
|
||||||
commands.run_system_cached(setup_balls);
|
fn setup_walls(
|
||||||
|
mut commands: Commands,
|
||||||
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
||||||
|
mut meshes: ResMut<Assets<Mesh>>,
|
||||||
|
) {
|
||||||
|
let thickness = 20.;
|
||||||
|
let width = AREA_WIDTH + thickness;
|
||||||
|
|
||||||
|
for i in 0..4 {
|
||||||
|
let mut transform = Transform::from_xyz(0., AREA_WIDTH / 2., 0.);
|
||||||
|
transform.rotate_around(Vec3::ZERO, Quat::from_rotation_z((i as f32) * PI / 2.));
|
||||||
|
commands.spawn((
|
||||||
|
Wall,
|
||||||
|
Collider::rectangle(width, thickness),
|
||||||
|
Mesh2d(meshes.add(Rectangle::new(width, thickness))),
|
||||||
|
MeshMaterial2d(materials.add(Color::from(WHITE))),
|
||||||
|
transform,
|
||||||
|
));
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Changes the timestep of the simulation when the up or down arrow keys are pressed.
|
fn move_player(
|
||||||
fn change_timestep(mut time: ResMut<Time<Fixed>>, keyboard_input: Res<ButtonInput<KeyCode>>) {
|
time: Res<Time>,
|
||||||
if keyboard_input.pressed(KeyCode::ArrowUp) {
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
||||||
let new_timestep = (time.delta_secs_f64() * 0.975).max(1.0 / 255.0);
|
mut player: Query<&mut LinearVelocity, With<Player>>,
|
||||||
time.set_timestep_seconds(new_timestep);
|
) {
|
||||||
|
let acceleration = 500.;
|
||||||
|
|
||||||
|
let mut velocity = player.single_mut();
|
||||||
|
let delta_time = time.delta_secs();
|
||||||
|
|
||||||
|
if keyboard_input.any_pressed([KeyCode::KeyW, KeyCode::ArrowUp]) {
|
||||||
|
velocity.y += acceleration * delta_time;
|
||||||
}
|
}
|
||||||
if keyboard_input.pressed(KeyCode::ArrowDown) {
|
if keyboard_input.any_pressed([KeyCode::KeyS, KeyCode::ArrowDown]) {
|
||||||
let new_timestep = (time.delta_secs_f64() * 1.025).min(1.0 / 5.0);
|
velocity.y -= acceleration * delta_time;
|
||||||
time.set_timestep_seconds(new_timestep);
|
}
|
||||||
|
if keyboard_input.any_pressed([KeyCode::KeyA, KeyCode::ArrowLeft]) {
|
||||||
|
velocity.x -= acceleration * delta_time;
|
||||||
|
}
|
||||||
|
if keyboard_input.any_pressed([KeyCode::KeyD, KeyCode::ArrowRight]) {
|
||||||
|
velocity.x += acceleration * delta_time;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn quit(mut exit: EventWriter<AppExit>) {
|
||||||
|
exit.send(AppExit::Success);
|
||||||
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue