Skip to content

Instantly share code, notes, and snippets.

@jordanhalase
Created April 17, 2024 02:08
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save jordanhalase/5cecebf1cc0ac77adc7ad524fc571a75 to your computer and use it in GitHub Desktop.
Save jordanhalase/5cecebf1cc0ac77adc7ad524fc571a75 to your computer and use it in GitHub Desktop.
Linear interpolation with a fixed timestep in Bevy v0.13.2 example
use bevy::prelude::*;
const PLAYER_SPEED: f32 = 500.0;
const PLAYER_SIZE: Vec3 = Vec3::new(32.0, 32.0, 0.0);
fn main() {
App::new()
.add_plugins(DefaultPlugins)
//.insert_resource(Time::<Fixed>::from_seconds(0.125)) // Test different timesteps here
.add_systems(Startup, spawn_player)
.add_systems(FixedPreUpdate, start_next_step)
.add_systems(FixedUpdate, move_player)
.add_systems(Update, interpolate_system)
.run();
}
#[derive(Component)]
struct Player;
#[derive(Component)]
struct Position(Vec2);
#[derive(Component)]
struct PositionOld(Vec2);
/// Spawn a white player that will be updated with a fixed timestep
fn spawn_player(mut commands: Commands) {
commands.spawn(Camera2dBundle::default());
commands.spawn((
SpriteBundle {
transform: Transform {
translation: Vec3::new(0.0, 0.0, 0.0),
scale: PLAYER_SIZE,
..default()
},
sprite: Sprite {
color: Color::WHITE,
..default()
},
..default()
},
Player,
Position(Vec2::ZERO),
PositionOld(Vec2::ZERO),
));
}
/// Move the current position into the old position before processing
fn start_next_step(mut query: Query<(&mut PositionOld, &Position)>) {
let (mut old, new) = query.single_mut();
old.0 = new.0;
}
/// Move the player in the fixed timestep
fn move_player(
keyboard_input: Res<ButtonInput<KeyCode>>,
mut query: Query<&mut Position, With<Player>>,
time: Res<Time>,
) {
let mut position = query.single_mut();
let mut direction = Vec2::new(0.0, 0.0);
if keyboard_input.pressed(KeyCode::ArrowLeft) {
direction.x -= 1.0;
}
if keyboard_input.pressed(KeyCode::ArrowRight) {
direction.x += 1.0;
}
if keyboard_input.pressed(KeyCode::ArrowUp) {
direction.y += 1.0;
}
if keyboard_input.pressed(KeyCode::ArrowDown) {
direction.y -= 1.0;
}
position.0 += direction * PLAYER_SPEED * time.delta_seconds();
}
/// Perform linear interpolation from old position to new position (runs in Update)
fn interpolate_system(
mut query: Query<(&PositionOld, &Position, &mut Transform)>,
time: Res<Time<Fixed>>,
) {
let (position_old, position, mut transform) = query.single_mut();
let delta = position.0 - position_old.0;
let lerped: Vec2 = position_old.0 + delta * time.overstep_fraction();
transform.translation = lerped.extend(0.0);
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment