use bevy::input::ButtonState; use bevy::prelude::*; use bevy::input::mouse::MouseButtonInput; use avian3d::prelude::*; use crate::physics::{ProjectileData, ProjectileSpawner}; use crate::ui::camera::CameraController; use crate::ui::cursor::CursorGrabState; mod target_wall; use target_wall::TargetWallPlugin; pub struct GamePlugin; impl Plugin for GamePlugin { fn build(&self, app: &mut App) { app.add_plugins(TargetWallPlugin); app.add_systems(Startup, setup_level); app.add_systems(Update, do_shoot_on_left_click .run_if(in_state(CursorGrabState(true))) .run_if(on_event::)) ; } } fn setup_level( mut commands: Commands, mut meshes: ResMut>, mut materials: ResMut>, ) { const GROUND_SIZE: f32 = 100.0; // spawn the camera commands.spawn(( CameraController { sensitivity: Vec2::new(0.0007, 0.0007), }, Camera3d::default(), Transform::from_xyz(0.0, 1.75, 0.0), )); // spawn the ground plane commands.spawn(( Mesh3d(meshes.add(Plane3d::new(Vec3::Y, Vec2::splat(GROUND_SIZE * 0.5)))), MeshMaterial3d(materials.add(StandardMaterial { base_color: Color::srgb(0.761, 0.698, 0.502), ..default() })), Transform::IDENTITY, Collider::cuboid(GROUND_SIZE, 0.0, GROUND_SIZE), RigidBody::Static, )); // spawn some boxes to shoot at for x in [0.0, 1.5, 3.0] { commands.spawn(( Mesh3d(meshes.add(Cuboid::from_corners( Vec3::ZERO, Vec3::ONE, ))), MeshMaterial3d(materials.add(StandardMaterial { base_color: Color::srgb(0.7, 0.1, 0.1), ..default() })), Transform::from_xyz(x, 0.5, -2.0), Collider::cuboid(1.0, 1.0, 1.0), RigidBody::Dynamic, )); } // spawn a light source commands.spawn(( DirectionalLight { illuminance: light_consts::lux::AMBIENT_DAYLIGHT, shadows_enabled: true, ..default() }, Transform::from_xyz(100.0, 200.0, 100.0).looking_at(Vec3::ZERO, Vec3::Y), )); } fn do_shoot_on_left_click( camera_query: Single<&GlobalTransform, With>, mut mouse_events: EventReader, mut projectiles: ResMut, ) { let camera_transform = camera_query.into_inner(); for _ in mouse_events.read() .filter(|event| event.button == MouseButton::Left) .filter(|event| event.state == ButtonState::Pressed) { projectiles.spawn(ProjectileData { position: camera_transform.translation(), direction: camera_transform.forward(), speed: 900.0, mass: 1.0, }); } }