Compare commits

..

No commits in common. 'a787e0e6c3cb55127b0d6a727d072567e1567993' and '1e42519a312d2a5ba28ee337933263906e4c2064' have entirely different histories.

@ -1,14 +1,12 @@
use std::f32::consts::PI; use std::f32::consts::PI;
use bevy::{ use bevy::{
input::common_conditions::input_just_pressed, input::common_conditions::input_just_pressed, prelude::*, render::{
prelude::*,
render::{
camera::RenderTarget, camera::RenderTarget,
render_resource::{ render_resource::{
Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
}, },
}, }
}; };
fn main() { fn main() {
@ -17,7 +15,8 @@ fn main() {
.add_systems(Startup, add_texture) .add_systems(Startup, add_texture)
.add_systems( .add_systems(
Update, Update,
rotate_mesh.run_if(input_just_pressed(KeyCode::Space)), rotate_mesh
.run_if(input_just_pressed(KeyCode::Space)),
) )
.run(); .run();
} }

@ -1,3 +1,5 @@
use bevy::input::mouse::MouseButtonInput;
use crate::prelude::*; use crate::prelude::*;
/// Menu Plugin; empty struct for Plugin impl /// Menu Plugin; empty struct for Plugin impl
@ -5,15 +7,8 @@ pub(crate) struct CameraPlugin;
impl Plugin for CameraPlugin { impl Plugin for CameraPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.add_systems( app.add_systems(Update, editor_fly_camera);
Update, }
move_editor_fly_camera.run_if(any_with_component::<FlyCamera>),
);
app.add_systems(
Update,
rotate_editor_fly_camera.run_if(any_with_component::<FlyCamera>),
);
}
} }
#[derive(Component)] #[derive(Component)]
@ -21,103 +16,74 @@ pub(crate) struct FlyCamera;
/// Fly camera system for moving around like a drone /// Fly camera system for moving around like a drone
/// TODO: Only if key is pressed! /// TODO: Only if key is pressed!
fn move_editor_fly_camera( fn editor_fly_camera(
mut cameras: Query<(&Camera, &mut Transform), With<FlyCamera>>, mut cameras: Query<(&Camera, &mut Transform), With<FlyCamera>>,
windows: Query<&Window>, windows: Query<&Window>,
primary_window: Query<Entity, With<PrimaryWindow>>, primary_window: Query<Entity, With<PrimaryWindow>>,
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
time: Res<Time>, mouse: Res<ButtonInput<MouseButton>>,
mut cursor_events: EventReader<CursorMoved>,
time: Res<Time>,
) { ) {
(keys.any_pressed([ let any_keys_pressed = keys.any_pressed([ KeyCode::KeyW, KeyCode::KeyS, KeyCode::KeyA, KeyCode::KeyD, KeyCode::KeyQ, KeyCode::KeyE ]);
KeyCode::KeyW, let cursor_movement = cursor_events.len() > 0;
KeyCode::KeyS,
KeyCode::KeyA,
KeyCode::KeyD,
KeyCode::KeyQ,
KeyCode::KeyE,
]))
.then(|| {
// Iterate over all cameras
cameras.iter_mut().for_each(|(c, mut t)| {
// Determine which window this camera is attached to
let target_window = match c.target {
RenderTarget::Window(wr) => match wr {
WindowRef::Entity(e) => Some(e),
WindowRef::Primary => Some(primary_window.get_single().unwrap()),
},
_ => None,
};
let window = windows.get(target_window.unwrap()).unwrap();
// If the target window is focused (any_keys_pressed || cursor_movement).then(|| {
window.focused.then(|| { // Iterate over all cameras
let move_speed = 4.0; cameras.iter_mut().for_each(|(c, mut t)| {
let mut delta = Vec3::ZERO; // Determine which window this camera is attached to
if keys.pressed(KeyCode::KeyW) { let target_window = match c.target {
delta += t.forward() * move_speed * time.delta_seconds() RenderTarget::Window(wr) => match wr {
} WindowRef::Entity(e) => Some(e),
if keys.pressed(KeyCode::KeyS) { WindowRef::Primary => Some(primary_window.get_single().unwrap()),
delta += t.back() * move_speed * time.delta_seconds() },
} _ => None,
if keys.pressed(KeyCode::KeyA) { };
delta += t.left() * move_speed * time.delta_seconds() let window = windows.get(target_window.unwrap()).unwrap();
}
if keys.pressed(KeyCode::KeyD) {
delta += t.right() * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyE) {
delta += Vec3::Y * move_speed * time.delta_seconds()
}
if keys.pressed(KeyCode::KeyQ) {
delta += Vec3::NEG_Y * move_speed * time.delta_seconds()
}
t.translation += delta;
});
});
});
}
fn rotate_editor_fly_camera( // If the target window is focused
mut cameras: Query<(&Camera, &mut Transform), With<FlyCamera>>, window.focused.then(|| {
windows: Query<&Window>, let move_speed = 4.0;
primary_window: Query<Entity, With<PrimaryWindow>>, let mut delta = Vec3::ZERO;
mouse: Res<ButtonInput<MouseButton>>, if keys.pressed(KeyCode::KeyW) {
mut cursor_events: EventReader<CursorMoved>, delta += t.forward() * move_speed * time.delta_seconds()
) { }
(cursor_events.len() > 0).then(|| { if keys.pressed(KeyCode::KeyS) {
// Iterate over all cameras delta += t.back() * move_speed * time.delta_seconds()
cameras.iter_mut().for_each(|(c, mut t)| { }
// Determine which window this camera is attached to if keys.pressed(KeyCode::KeyA) {
let target_window = match c.target { delta += t.left() * move_speed * time.delta_seconds()
RenderTarget::Window(wr) => match wr { }
WindowRef::Entity(e) => Some(e), if keys.pressed(KeyCode::KeyD) {
WindowRef::Primary => Some(primary_window.get_single().unwrap()), delta += t.right() * move_speed * time.delta_seconds()
}, }
_ => None, if keys.pressed(KeyCode::KeyE) {
}; delta += Vec3::Y * move_speed * time.delta_seconds()
let window = windows.get(target_window.unwrap()).unwrap(); }
if mouse.pressed(MouseButton::Middle) { if keys.pressed(KeyCode::KeyQ) {
cursor_events delta += Vec3::NEG_Y * move_speed * time.delta_seconds()
.read() }
.filter_map(|CursorMoved { delta, window, .. }| { t.translation += delta;
(*window == target_window.unwrap()).then_some(delta) });
})
.for_each(|delta| { if mouse.pressed(MouseButton::Middle) {
if let Some(Vec2 { x, y }) = delta { cursor_events.read().filter_map(|CursorMoved { delta, window, .. }| {
// Cribbing from bevy_flycam (*window == target_window.unwrap()).then_some(delta)
// Link: https://github.com/sburris0/bevy_flycam/blob/baffe50e0961ad1491d467fa6ab5551f9f21db8f/src/lib.rs#L145-L151 }).for_each(|delta| {
let (mut yaw, mut pitch, _) = t.rotation.to_euler(EulerRot::YXZ); if let Some(Vec2 { x, y }) = delta {
let window_scale = window.height().min(window.width()); // Cribbing from bevy_flycam
let sensitivity = 0.00012; // Link: https://github.com/sburris0/bevy_flycam/blob/baffe50e0961ad1491d467fa6ab5551f9f21db8f/src/lib.rs#L145-L151
pitch -= (sensitivity * y * window_scale).to_radians(); let (mut yaw, mut pitch, _) = t.rotation.to_euler(EulerRot::YXZ);
yaw -= (sensitivity * x * window_scale).to_radians(); let window_scale = window.height().min(window.width());
t.rotation = Quat::from_axis_angle(Vec3::Y, yaw) let sensitivity = 0.00012;
* Quat::from_axis_angle(Vec3::X, pitch); pitch -= (sensitivity * y * window_scale).to_radians();
} yaw -= (sensitivity * x * window_scale).to_radians();
}); t.rotation = Quat::from_axis_angle(Vec3::Y, yaw) * Quat::from_axis_angle(Vec3::X, pitch);
} else { }
cursor_events.clear(); });
} } else {
}); cursor_events.clear();
}); }
});
});
} }

@ -5,118 +5,117 @@ pub(crate) struct EditorPlugin;
impl Plugin for EditorPlugin { impl Plugin for EditorPlugin {
fn build(&self, app: &mut App) { fn build(&self, app: &mut App) {
app.init_state::<EditorState>(); app.init_state::<EditorState>();
app.add_systems(Startup, init_editor); app.add_systems(Startup, init_editor);
app.add_systems( app.add_systems(Update, toggle_editor.run_if(input_just_pressed(KeyCode::F3)));
Update, app.add_systems(OnEnter(EditorState::Open), open_editor);
toggle_editor.run_if(input_just_pressed(KeyCode::F3)), app.add_systems(OnExit(EditorState::Open), close_editor);
); app.add_systems(Update, origin_directions.run_if(in_state(EditorState::Open)));
app.add_systems(OnEnter(EditorState::Open), open_editor); app.add_systems(Update, world_plane.run_if(in_state(EditorState::Open)));
app.add_systems(OnExit(EditorState::Open), close_editor); }
app.add_systems(
Update,
origin_directions.run_if(in_state(EditorState::Open)),
);
app.add_systems(Update, world_plane.run_if(in_state(EditorState::Open)));
}
} }
/// State tracking if the editor is open /// State tracking if the editor is open
#[derive(States, Debug, Clone, PartialEq, Eq, Hash, Default, Component)] #[derive(States, Debug, Clone, PartialEq, Eq, Hash, Default, Component)]
enum EditorState { enum EditorState {
#[default] #[default]
Closed, Closed,
Open, Open,
} }
#[derive(Component)] #[derive(Component)]
struct Editor; struct Editor;
/// Spawns all base editor entities including window, camera, and UI elements /// Spawns all base editor entities including window, camera, and UI elements
fn init_editor(mut commands: Commands) { fn init_editor(
// Spawn root editor entity hierarchy mut commands: Commands
commands ) {
.spawn(SpatialBundle { ..default() }) // Spawn root editor entity hierarchy
.with_children(|parent| { commands.spawn(SpatialBundle { ..default() })
let editor_window = parent .with_children(|parent| {
.spawn((
Editor, let editor_window = parent.spawn((
Window { Editor,
title: "Editor".into(), Window {
name: Some("Editor".into()), title: "Editor".into(),
visible: false, name: Some("Editor".into()),
..default() visible: false,
}, ..default()
)) },
.id(); )).id();
// Spawn editor camera // Spawn editor camera
let _editor_camera = parent let _editor_camera = parent.spawn((
.spawn(( Editor,
Editor, FlyCamera,
FlyCamera, Camera3dBundle {
Camera3dBundle { camera: Camera {
camera: Camera { target: RenderTarget::Window(WindowRef::Entity(editor_window)),
target: RenderTarget::Window(WindowRef::Entity(editor_window)), ..default()
..default() },
}, transform: Transform::from_xyz(1.0, 1.0, 1.0).looking_at(Vec3::ZERO, Vec3::Y),
transform: Transform::from_xyz(1.0, 1.0, 1.0) ..default()
.looking_at(Vec3::ZERO, Vec3::Y), },
..default() )).id();
}, });
))
.id();
});
} }
fn open_editor(mut ws: Query<&mut Window, With<Editor>>) { fn open_editor(
ws.iter_mut().for_each(|mut w| { mut ws: Query<&mut Window, With<Editor>>,
w.visible = true; ) {
}); ws.iter_mut().for_each(|mut w| {
w.visible = true;
});
} }
fn close_editor(mut ws: Query<&mut Window, With<Editor>>) { fn close_editor(
ws.iter_mut().for_each(|mut w| { mut ws: Query<&mut Window, With<Editor>>,
w.visible = false; ) {
}); ws.iter_mut().for_each(|mut w| {
w.visible = false;
});
} }
fn toggle_editor( fn toggle_editor(
state: Res<State<EditorState>>, state: Res<State<EditorState>>,
mut next_state: ResMut<NextState<EditorState>>, mut next_state: ResMut<NextState<EditorState>>,
keys: Res<ButtonInput<KeyCode>>, keys: Res<ButtonInput<KeyCode>>,
mut catch: Local<bool>, mut catch: Local<bool>,
) { ) {
if keys.pressed(KeyCode::F3) && !*catch { if keys.pressed(KeyCode::F3) && !*catch {
*catch = true; *catch = true;
match state.get() { match state.get() {
EditorState::Open => next_state.set(EditorState::Closed), EditorState::Open => next_state.set(EditorState::Closed),
EditorState::Closed => next_state.set(EditorState::Open), EditorState::Closed => next_state.set(EditorState::Open),
} }
} else { } else {
*catch = false; *catch = false;
} }
} }
fn origin_directions(mut gizmos: Gizmos) { fn origin_directions(
gizmos.arrow(Vec3::ZERO, Vec3::X, Color::RED); mut gizmos: Gizmos
gizmos.arrow(Vec3::ZERO, Vec3::Y, Color::GREEN); ) {
gizmos.arrow(Vec3::ZERO, Vec3::Z, Color::BLUE); gizmos.arrow(Vec3::ZERO, Vec3::X, Color::RED);
gizmos.arrow(Vec3::ZERO, Vec3::Y, Color::GREEN);
gizmos.arrow(Vec3::ZERO, Vec3::Z, Color::BLUE);
} }
fn world_plane(mut gizmos: Gizmos) { fn world_plane(
(-10..=10).into_iter().for_each(|x| { mut gizmos: Gizmos
(-10..=10).into_iter().for_each(|z| { ) {
{ (-10..=10).into_iter().for_each(|x| {
let start = Vec3::new(x as f32, 0.0, -10.0); (-10..=10).into_iter().for_each(|z| {
let end = Vec3::new(x as f32, 0.0, 10.0); {
gizmos.line(start, end, Color::GRAY); let start = Vec3::new(x as f32, 0.0, -10.0);
} let end = Vec3::new(x as f32, 0.0, 10.0);
{ gizmos.line(start, end, Color::GRAY);
let start = Vec3::new(-10.0, 0.0, z as f32); }
let end = Vec3::new(10.0, 0.0, z as f32); {
gizmos.line(start, end, Color::GRAY); let start = Vec3::new(-10.0, 0.0, z as f32);
} let end = Vec3::new(10.0, 0.0, z as f32);
}); gizmos.line(start, end, Color::GRAY);
}); }
});
});
} }

@ -141,20 +141,22 @@ fn move_die(
}| { }| {
match state { match state {
ButtonState::Pressed => { ButtonState::Pressed => {
q.iter_mut().for_each(|mut t| match key_code { q.iter_mut().for_each(|mut t| {
KeyCode::ArrowLeft => { match key_code {
t.translation -= Vec3::X * time.delta_seconds() * 1000.0 KeyCode::ArrowLeft => {
t.translation -= Vec3::X * time.delta_seconds() * 1000.0
}
KeyCode::ArrowRight => {
t.translation += Vec3::X * time.delta_seconds() * 1000.0
}
KeyCode::ArrowDown => {
t.translation -= Vec3::Y * time.delta_seconds() * 1000.0
}
KeyCode::ArrowUp => {
t.translation += Vec3::Y * time.delta_seconds() * 1000.0
}
_ => (),
} }
KeyCode::ArrowRight => {
t.translation += Vec3::X * time.delta_seconds() * 1000.0
}
KeyCode::ArrowDown => {
t.translation -= Vec3::Y * time.delta_seconds() * 1000.0
}
KeyCode::ArrowUp => {
t.translation += Vec3::Y * time.delta_seconds() * 1000.0
}
_ => (),
}); });
} }
_ => (), _ => (),

@ -29,14 +29,13 @@ use crate::prelude::*;
fn main() { fn main() {
let mut app = App::new(); let mut app = App::new();
app.add_plugins( app.add_plugins(bevy::DefaultPlugins
bevy::DefaultPlugins .set(low_latency_window_plugin())
.set(low_latency_window_plugin()) .set(WindowPlugin {
.set(WindowPlugin { exit_condition: ExitCondition::OnPrimaryClosed,
exit_condition: ExitCondition::OnPrimaryClosed, close_when_requested: false,
close_when_requested: false, ..default()
..default() })
}),
); );
app.add_plugins(bevy_mod_picking::DefaultPickingPlugins); app.add_plugins(bevy_mod_picking::DefaultPickingPlugins);
app.add_plugins(menu::MenuPlugin); app.add_plugins(menu::MenuPlugin);
@ -44,9 +43,8 @@ fn main() {
app.add_plugins(game::GamePlugin); app.add_plugins(game::GamePlugin);
app.add_plugins(editor::EditorPlugin); app.add_plugins(editor::EditorPlugin);
app.add_plugins(camera::CameraPlugin); app.add_plugins(camera::CameraPlugin);
app.add_systems( app.add_systems(Update,
Update, handle_window_close.run_if(on_event::<WindowCloseRequested>())
handle_window_close.run_if(on_event::<WindowCloseRequested>()),
); );
app.run(); app.run();
} }
@ -77,9 +75,12 @@ fn handle_window_close(
if primary.contains(*window) { if primary.contains(*window) {
commands.entity(*window).remove::<Window>(); commands.entity(*window).remove::<Window>();
} else { } else {
secondary.get_mut(*window).iter_mut().for_each(|w| { secondary
w.visible = false; .get_mut(*window)
}); .iter_mut()
.for_each(|w| {
w.visible = false;
});
} }
}); });
} }

@ -2,7 +2,6 @@ pub(crate) use std::fmt::Debug;
/// Bevy imports /// Bevy imports
pub(crate) use bevy::ecs::system::EntityCommand; pub(crate) use bevy::ecs::system::EntityCommand;
pub(crate) use bevy::input::common_conditions::input_just_pressed;
pub(crate) use bevy::input::keyboard::KeyboardInput; pub(crate) use bevy::input::keyboard::KeyboardInput;
pub(crate) use bevy::input::ButtonState; pub(crate) use bevy::input::ButtonState;
pub(crate) use bevy::prelude::*; pub(crate) use bevy::prelude::*;
@ -10,14 +9,14 @@ pub(crate) use bevy::render::camera::RenderTarget;
pub(crate) use bevy::render::render_resource::{ pub(crate) use bevy::render::render_resource::{
Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages, Extent3d, TextureDescriptor, TextureDimension, TextureFormat, TextureUsages,
}; };
pub(crate) use bevy::window::ExitCondition;
pub(crate) use bevy::window::WindowRef; pub(crate) use bevy::window::WindowRef;
pub(crate) use bevy::window::{PrimaryWindow, WindowCloseRequested}; pub(crate) use bevy::window::{PrimaryWindow, WindowCloseRequested};
pub(crate) use bevy::window::ExitCondition;
pub(crate) use bevy::input::common_conditions::input_just_pressed;
/// Bevy Plugins /// Bevy Plugins
pub(crate) use bevy_mod_picking::prelude::*; pub(crate) use bevy_mod_picking::prelude::*;
pub(crate) use crate::camera::FlyCamera;
/// Intra-project imports /// Intra-project imports
pub(crate) use crate::ecs::schedule::common_conditions::*; pub(crate) use crate::ecs::schedule::common_conditions::*;
pub(crate) use crate::game::GameChoice; pub(crate) use crate::game::GameChoice;
@ -31,3 +30,4 @@ pub(crate) use crate::ui::style::UiStyle;
pub(crate) use crate::ui::title::UiTitle; pub(crate) use crate::ui::title::UiTitle;
pub(crate) use crate::ui::EmitEvent; pub(crate) use crate::ui::EmitEvent;
pub(crate) use crate::ui::SetState; pub(crate) use crate::ui::SetState;
pub(crate) use crate::camera::FlyCamera;

Loading…
Cancel
Save