Created
August 28, 2022 17:15
-
-
Save ian-h-chamberlain/4a5d497e99b69ceae7de58d3c8eb8b52 to your computer and use it in GitHub Desktop.
bevy_rapier2d add children example
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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