You cannot select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
156 lines
4.3 KiB
Rust
156 lines
4.3 KiB
Rust
use avian3d::math::Vector;
|
|
// TEMP
|
|
use avian2d::prelude::*;
|
|
use bevy::{color::palettes::css::*, prelude::*};
|
|
|
|
fn main() {
|
|
App::new()
|
|
.add_plugins(DefaultPlugins)
|
|
.add_plugins(PhysicsPlugins::default())
|
|
.insert_resource(ClearColor(WHITE.into()))
|
|
.add_systems(Startup, setup)
|
|
.add_systems(Update, move_player)
|
|
.add_systems(Update, follow_player)
|
|
.add_systems(Update, draw_gizmos)
|
|
.add_systems(
|
|
Update,
|
|
event_detection.run_if(on_event::<CollisionStarted>.or(on_event::<CollisionEnded>)),
|
|
)
|
|
.add_observer(set_tree_position)
|
|
.run();
|
|
}
|
|
|
|
#[derive(Component)]
|
|
struct Player;
|
|
|
|
#[derive(Component)]
|
|
struct RenderGizmo;
|
|
|
|
#[derive(Component)]
|
|
struct PlayArea;
|
|
|
|
#[derive(Component, Debug)]
|
|
struct TreePos(isize);
|
|
|
|
fn setup(
|
|
mut commands: Commands,
|
|
mut meshes: ResMut<Assets<Mesh>>,
|
|
mut materials: ResMut<Assets<ColorMaterial>>,
|
|
) {
|
|
commands.spawn(Camera2d);
|
|
|
|
// Spawn "trees" (which are also sensors)
|
|
[
|
|
("TREE -3", -3),
|
|
("TREE -2", -2),
|
|
("TREE -2", -1),
|
|
("TREE 1", 1),
|
|
("TREE 2", 2),
|
|
("TREE 3", 3),
|
|
]
|
|
.iter()
|
|
.for_each(|(label, pos)| {
|
|
commands.spawn((
|
|
RigidBody::Static,
|
|
Collider::rectangle(100.0, 250.0),
|
|
Mesh2d(meshes.add(Rectangle::new(100.0, 250.0))),
|
|
MeshMaterial2d(materials.add(Color::from(GREEN))),
|
|
TreePos(*pos),
|
|
children![Text2d::new(*label),],
|
|
));
|
|
});
|
|
|
|
commands.spawn((
|
|
Player,
|
|
RigidBody::Kinematic,
|
|
ExternalImpulse::default().with_persistence(true),
|
|
Collider::rectangle(50.0, 50.0),
|
|
Mesh2d(meshes.add(Rectangle::new(50.0, 50.0))),
|
|
MeshMaterial2d(materials.add(Color::from(RED))),
|
|
children![
|
|
(
|
|
Text2d::new("PLAYER"),
|
|
Transform::from_scale(Vec3::new(0.5, 0.5, 0.5)),
|
|
),
|
|
(
|
|
Text2d::new("PLAY AREA"),
|
|
Transform::from_xyz(0.0, 212.0, 1.0),
|
|
TextColor(BLACK.into())
|
|
),
|
|
(
|
|
RenderGizmo,
|
|
PlayArea,
|
|
Visibility::Visible,
|
|
Transform::from_scale(Vec3::new(400.0, 400.0, 0.0)),
|
|
),
|
|
],
|
|
));
|
|
}
|
|
|
|
fn set_tree_position(
|
|
trigger: Trigger<OnAdd, TreePos>,
|
|
tree_pos: Query<&TreePos>,
|
|
mut commands: Commands,
|
|
) {
|
|
let TreePos(pos) = tree_pos.get(trigger.target()).unwrap();
|
|
let x = if (*pos) > 0 {
|
|
(200.0 * (*pos) as f32) - 100.0
|
|
} else {
|
|
(200.0 * (*pos) as f32) + 100.0
|
|
};
|
|
let t = Transform::from_xyz(x, 0.0, 0.0);
|
|
commands.entity(trigger.target()).insert(t);
|
|
}
|
|
|
|
fn move_player(
|
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
mut player: Single<&mut ExternalImpulse, With<Player>>,
|
|
) {
|
|
const SPEED: f32 = 5.0;
|
|
if keyboard_input.pressed(KeyCode::ArrowLeft) {
|
|
player.set_impulse(Vec2::NEG_X * SPEED);
|
|
} else if keyboard_input.pressed(KeyCode::ArrowRight) {
|
|
player.set_impulse(Vec2::X * SPEED);
|
|
}
|
|
}
|
|
|
|
fn follow_player(
|
|
player: Query<&Transform, (With<Player>, Changed<Transform>)>,
|
|
mut camera: Single<&mut Transform, (With<Camera2d>, Without<Player>)>,
|
|
) {
|
|
player.iter().for_each(|pt| {
|
|
camera.translation = pt.translation;
|
|
});
|
|
}
|
|
|
|
fn draw_gizmos(mut gizmos: Gizmos, play_area: Single<&GlobalTransform, With<RenderGizmo>>) {
|
|
gizmos.rect_2d(
|
|
play_area.translation().truncate(),
|
|
play_area.scale().truncate(),
|
|
MAGENTA,
|
|
)
|
|
}
|
|
|
|
fn event_detection(
|
|
mut start_events: EventReader<CollisionStarted>,
|
|
mut end_events: EventReader<CollisionEnded>,
|
|
player: Single<&Player>,
|
|
trees: Query<&TreePos>,
|
|
keyboard_input: Res<ButtonInput<KeyCode>>,
|
|
) {
|
|
debug_assert!(!(start_events.is_empty() && end_events.is_empty()));
|
|
let s = start_events.read().map(|CollisionStarted(a, b)| (a, b));
|
|
let e = end_events.read().map(|CollisionEnded(a, b)| (a, b));
|
|
let mut events = s.chain(e);
|
|
let current_tree = events.find_map(|(a, b)| {
|
|
info!("{a:?}, {b:?}");
|
|
trees.get(*a).or(trees.get(*b)).ok()
|
|
});
|
|
info!("{:?}", current_tree);
|
|
if keyboard_input.pressed(KeyCode::ArrowLeft) {
|
|
// moving left
|
|
} else if keyboard_input.pressed(KeyCode::ArrowRight) {
|
|
// moving right
|
|
}
|
|
}
|