Skip to content

Instantly share code, notes, and snippets.

@ian-h-chamberlain
Created August 28, 2022 17:15
Show Gist options
  • Save ian-h-chamberlain/4a5d497e99b69ceae7de58d3c8eb8b52 to your computer and use it in GitHub Desktop.
Save ian-h-chamberlain/4a5d497e99b69ceae7de58d3c8eb8b52 to your computer and use it in GitHub Desktop.
bevy_rapier2d add children example
use bevy::prelude::*;
use bevy_rapier2d::prelude::*;
fn main() {
App::new()
.insert_resource(WindowDescriptor {
title: "Player Movement Example".to_string(),
width: 1000.0,
height: 1000.0,
..Default::default()
})
.add_plugins(DefaultPlugins)
.add_startup_system(spawn_player)
.add_system(player_movement)
.add_plugin(RapierPhysicsPlugin::<NoUserData>::pixels_per_meter(100.0))
.add_plugin(RapierDebugRenderPlugin::default())
.run();
}
// The float value is the player movement speed in 'pixels/second'.
#[derive(Component)]
struct Player(f32);
fn spawn_player(mut commands: Commands, mut rapier_config: ResMut<RapierConfiguration>) {
// Set gravity to 0.0 and spawn camera.
rapier_config.gravity = Vec2::ZERO;
commands.spawn().insert_bundle(Camera2dBundle::default());
let sprite_size = 100.0;
// Spawn entity with `Player` struct as a component for access in movement query.
commands
.spawn()
.insert_bundle(SpriteBundle {
sprite: Sprite {
color: Color::rgb(0.0, 0.0, 0.0),
custom_size: Some(Vec2::new(sprite_size, sprite_size)),
..Default::default()
},
..Default::default()
})
.insert(RigidBody::Dynamic)
.insert(Velocity::zero())
.insert(Collider::ball(sprite_size / 2.0))
.insert(Player(100.0));
}
fn player_movement(
mut commands: Commands,
keyboard_input: Res<Input<KeyCode>>,
mut player_info: Query<(&Player, &GlobalTransform, &mut Velocity, Entity)>,
mut parentless_colliders: Query<
(Entity, &GlobalTransform, &mut Transform),
(With<Collider>, Without<Parent>, Without<Player>),
>,
) {
for (player, transform, mut rb_vels, player_entity) in player_info.iter_mut() {
let up = keyboard_input.pressed(KeyCode::W) || keyboard_input.pressed(KeyCode::Up);
let down = keyboard_input.pressed(KeyCode::S) || keyboard_input.pressed(KeyCode::Down);
let left = keyboard_input.pressed(KeyCode::A) || keyboard_input.pressed(KeyCode::Left);
let right = keyboard_input.pressed(KeyCode::D) || keyboard_input.pressed(KeyCode::Right);
let x_axis = -(left as i8) + right as i8;
let y_axis = -(down as i8) + up as i8;
let mut move_delta = Vec2::new(x_axis as f32, y_axis as f32);
if move_delta != Vec2::ZERO {
move_delta /= move_delta.length();
}
// Update the velocity on the rigid_body_component,
// the bevy_rapier plugin will update the Sprite transform.
rb_vels.linvel = move_delta * player.0;
let spawn_child = keyboard_input.just_pressed(KeyCode::Space);
let join_children = keyboard_input.just_pressed(KeyCode::Return);
if spawn_child {
let child_translation = transform.translation() - rb_vels.linvel.extend(0.0);
commands
.spawn_bundle(SpriteBundle {
sprite: Sprite {
color: Color::rgb(0.3, 0.3, 0.3),
custom_size: Some(Vec2::new(50.0, 50.0)),
..Default::default()
},
transform: transform
.compute_transform()
.with_translation(child_translation),
..Default::default()
})
.insert(Collider::ball(25.0));
}
if join_children {
for (child, child_transform, mut new_transform) in &mut parentless_colliders {
let relative_transform =
transform.compute_matrix().inverse() * child_transform.compute_matrix();
*new_transform = Transform::from_matrix(relative_transform);
commands.entity(player_entity).add_child(child);
commands.entity(child).insert(rb_vels.clone());
}
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment