bevy_fps/src/game/mod.rs

106 lines
2.8 KiB
Rust

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::<MouseButtonInput>))
;
}
}
fn setup_level(
mut commands: Commands,
mut meshes: ResMut<Assets<Mesh>>,
mut materials: ResMut<Assets<StandardMaterial>>,
) {
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<Camera>>,
mut mouse_events: EventReader<MouseButtonInput>,
mut projectiles: ResMut<ProjectileSpawner>,
) {
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,
});
}
}