Untitled

mail@pastecode.io avatar
unknown
rust
6 months ago
6.3 kB
1
Indexable
Never
use bevy::prelude::*;
use bevy_rapier3d::prelude::*;
use bevy_third_person_camera::*;

use crate::game::player::components::*;

pub fn setup(
    mut commands: Commands,
    _meshes: ResMut<Assets<Mesh>>,
    _materials: ResMut<Assets<StandardMaterial>>,
    asset_server: Res<AssetServer>,
    spawn_tools: Res<SpawnToolsVec>,
) {
    let player_mesh: Handle<Scene> = asset_server.load("meshes/player.glb#Scene0");

    let tool_data = vec![
        ("Shovel", 10, "meshes/shovel.glb#Scene0"),
        // Add more tools as needed
    ];

    let player = (
        SceneBundle {
            scene: player_mesh,
            transform: Transform::from_xyz(0.0, 1.0, 0.0),
            ..Default::default()
        },
        Player {},
        ThirdPersonCameraTarget,
        RigidBody::Dynamic,
        GravityScale(1.0),
        ExternalImpulse {
            impulse: Vec3::new(0.0, 0.0, 0.0),
            torque_impulse: Vec3::new(0.0, 00.0, 0.0),
        },
        ActiveEvents::CONTACT_FORCE_EVENTS,
        (LockedAxes::ROTATION_LOCKED_X
            | LockedAxes::ROTATION_LOCKED_Z
            | LockedAxes::ROTATION_LOCKED_Y),
        Collider::capsule(
            Vec3 {
                x: (0.0),
                y: (0.3),
                z: (0.0),
            },
            Vec3 {
                x: (0.0),
                y: (1.2),
                z: (0.0),
            },
            0.85,
        ),
        KinematicCharacterController {
            offset: CharacterLength::Absolute(0.01),
            max_slope_climb_angle: 45.0_f32.to_radians(),
            min_slope_slide_angle: 20.0_f32.to_radians(),
            autostep: Some(CharacterAutostep {
                max_height: CharacterLength::Absolute(0.5),
                min_width: CharacterLength::Absolute(0.2),
                include_dynamic_bodies: true,
            }),
            snap_to_ground: Some(CharacterLength::Absolute(0.2)),
            ..Default::default()
        },
        Speed(5.0),
    );

    for (name, collect_amount, mesh_path) in tool_data {
        let mesh_handle = asset_server.load(mesh_path);
        let collector = (
            SceneBundle {
                scene: asset_server.load(mesh_path),
                transform: Transform::from_xyz(
                    spawn_tools.spawn_tools_vec.x,
                    spawn_tools.spawn_tools_vec.y,
                    spawn_tools.spawn_tools_vec.z,
                ),
                ..Default::default()
            },
            Collector {
                name: name.to_string(),
                collect_amount,
                mesh_handle,
            },
        );

        commands.spawn(collector);
    }

    commands.spawn(player);

    let camera = (
        Camera3dBundle {
            transform: Transform::from_xyz(-2.0, 3.0, 0.0).looking_at(Vec3::ZERO, Vec3::Y),
            ..default()
        },
        ThirdPersonCamera {
            mouse_sensitivity: 6.0,
            cursor_lock_key: KeyCode::F,
            zoom: Zoom::new(2.0, 15.0),
            offset_enabled: true,
            offset: Offset::new(0.0, 1.6),
            ..Default::default()
        },
    );
    commands.spawn(camera);
}

pub fn player_movement(
    time: Res<Time>,
    keys: Res<Input<KeyCode>>,
    cam_q: Query<&Transform, (With<Camera3d>, Without<Player>)>,
    on_ground: Res<OnGround>,
    mut player_q: Query<(&mut Transform, &Speed), With<Player>>,
    mut ext_impulses: Query<&mut ExternalImpulse>,
    mut spawn_tools_vec_q: ResMut<SpawnToolsVec>,
) {
    for (mut player_transform, player_speed) in player_q.iter_mut() {
        let cam = match cam_q.get_single() {
            Ok(c) => c,
            Err(e) => Err(format!("Error retrieving camera: {}", e)).unwrap(),
        };

        let mut direction = Vec3::ZERO;

        // forward
        if keys.pressed(KeyCode::W) {
            direction += cam.forward();
        }

        // back
        if keys.pressed(KeyCode::S) {
            direction += cam.back();
        }

        // left
        if keys.pressed(KeyCode::A) {
            direction += cam.left();
        }

        // right
        if keys.pressed(KeyCode::D) {
            direction += cam.right();
        }

        if keys.pressed(KeyCode::Space) && on_ground.is_grounded {
            for mut ext_impulse in ext_impulses.iter_mut() {
                ext_impulse.impulse = Vec3::new(0.0, 15.0, 0.0);
                ext_impulse.torque_impulse = Vec3::new(0.0, 0.5, 0.0);
            }
        }

        let mut movement = direction.normalize_or_zero() * player_speed.0 * time.delta_seconds();

        movement.y = 0.0;
        direction.y = 0.0;

        player_transform.translation += movement;
        spawn_tools_vec_q.spawn_tools_vec = player_transform.translation;
        spawn_tools_vec_q.spawn_tools_vec.x += 0.7;
        spawn_tools_vec_q.spawn_tools_vec.y += 0.3;
        spawn_tools_vec_q.tool_rotation = player_transform.rotation;

        // rotate player to face direction he is currently moving
        if direction.length_squared() > 0.0 {
            player_transform.look_to(direction, Vec3::Y);
        }
    }
}

/* A system that displays the events. */
pub fn is_grounded(
    mut contact_force_events: EventReader<ContactForceEvent>,
    mut on_ground: ResMut<OnGround>,
    player_q: Query<Entity, With<Player>>,
) {
    let player = player_q.single();

    on_ground.is_grounded = false;

    for contact_force_event in contact_force_events.read() {
        let entity_1 = contact_force_event.collider1;
        let entity_2 = contact_force_event.collider2;

        on_ground.is_grounded = (entity_1 == player) || (entity_2 == player);
    }
}

pub fn tools(mut tool_q: Query<&mut Transform, With<Collector>>, vec3: Res<SpawnToolsVec>) {
    let mut tool = match tool_q.get_single_mut() {
        Ok(c) => c,
        Err(e) => Err(format!("Error retrieving tool: {}", e)).unwrap(),
    };

    *tool = Transform::from_xyz(
        vec3.spawn_tools_vec.x,
        vec3.spawn_tools_vec.y,
        vec3.spawn_tools_vec.z,
    );

    tool.rotation = vec3.tool_rotation;
}
Leave a Comment