1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
|
use avian2d::prelude::*;
use bevy::prelude::*;
use crate::{lunar::DestPlanet, Stickable, TouchdownGoal};
#[derive(Component)]
pub struct Player {
pub velocity: f32,
pub display_name: Text2d,
pub mass_kg: f32,
}
pub struct ControlledObject {}
enum Direction {
Up,
Down,
Left,
Right,
None,
}
fn map_key_to_movement(key: &KeyCode) -> Direction {
match key {
KeyCode::KeyW => Direction::Up,
KeyCode::KeyS => Direction::Down,
KeyCode::KeyA => Direction::Left,
KeyCode::KeyD => Direction::Right,
_ => Direction::None,
}
}
pub fn check_transition_level(
mut has_touched_down: ResMut<TouchdownGoal>,
player_transform: Query<&Transform, (With<Player>, Without<DestPlanet>)>,
moon_transform: Query<(Entity, &DestPlanet, &Transform), (With<DestPlanet>, Without<Player>)>
) {
if has_touched_down.reached {return;}
let (moon_e, moon, moon_t) = moon_transform.single();
let player_t = player_transform.single();
let shroud_padding = 0.1 + moon.radius;
let bounds = (
Vec2 {
x: moon_t.translation.x - shroud_padding,
y: moon_t.translation.y - shroud_padding,
},
Vec2 {
x: moon_t.translation.x + shroud_padding,
y: moon_t.translation.y + shroud_padding,
}
);
if player_t.translation.x > bounds.0.x &&
player_t.translation.x < bounds.1.x &&
player_t.translation.y > bounds.0.y &&
player_t.translation.y < bounds.1.y {
info!("CAN TRANSITION TO NEXT LEVEL");
// has_touched_down.reached = true;
// commands.entity(moon_e).despawn();
}
}
pub fn camera_follow_player(
goal: Res<TouchdownGoal>,
mut camera_transform: Query<&mut Transform, (With<Camera2d>, Without<Player>)>,
player_transform: Query<&Transform, (With<Player>, Without<Camera>)>,
) {
if goal.reached {return;}
let mut camera_t = camera_transform.single_mut();
let player_t = player_transform.single();
camera_t.translation = player_t.translation;
}
pub fn player_movements(
time: Res<Time>,
input: Res<ButtonInput<KeyCode>>,
goal: Res<TouchdownGoal>,
mut ps: Query<(&Player, &Sprite, &mut ExternalForce), (With<Player>)>,
) {
if goal.reached { return; }
let movements: Vec<Direction> = input.get_pressed().map(map_key_to_movement).collect();
for (p, s, mut propulsion) in &mut ps {
let mut pvel_vec = Vec2 { x: 0., y: 0. };
let pv = p.velocity;
movements.iter().for_each(|m| match m {
Direction::Up => pvel_vec.y = pv,
Direction::Down => pvel_vec.y = -pv,
Direction::Left => pvel_vec.x = -pv,
Direction::Right => pvel_vec.x = pv,
Direction::None => pvel_vec = Vec2 { x: 0., y: 0. },
});
let pvv = pvel_vec.normalize_or_zero();
propulsion.apply_force(pvv * pv);
}
}
pub fn setup_player_with_controls(mut commands: Commands) {
commands.spawn((
Player {
velocity: 20000.0,
display_name: Text2d("Main player".to_string()),
mass_kg: 100.,
},
RigidBody::Dynamic,
Transform::from_xyz(0., 70., 0.),
Stickable {},
ExternalForce::ZERO.with_persistence(false),
Sprite::from_color(Color::BLACK, Vec2 { x: 10., y: 10. }),
Collider::rectangle(10., 10.),
));
}
|