Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- use crate::{
- capsule::Capsule,
- collision::{Collidable, Collider},
- camera::Camera,
- renderable::Renderable,
- };
- use nalgebra::Vector3;
- use sdl2::keyboard::KeyboardState;
- pub struct Player {
- pub body: Capsule,
- pub velocity: Vector3<f32>,
- pub speed: f32,
- pub jump_speed: f32,
- pub gravity: f32,
- pub on_ground: bool,
- pub camera_offset: Vector3<f32>,
- }
- impl Player {
- pub fn new(spawn_pos: Vector3<f32>, eye_height: f32) -> Player {
- let scale = Vector3::new(1.0, 2.0, 1.0);
- let half_h = 1.0 * scale.y;
- let center_y = spawn_pos.y + half_h;
- let body = Capsule::new(
- Vector3::new(spawn_pos.x, center_y, spawn_pos.z),
- Vector3::zeros(),
- scale,
- Vector3::new(0.2, 0.4, 1.0),
- 16, 8,
- );
- let cam_off = Vector3::new(0.0, eye_height - half_h, 0.0);
- Player {
- body,
- velocity: Vector3::zeros(),
- speed: 6.0,
- jump_speed: 8.0,
- gravity: -9.81,
- on_ground: false,
- camera_offset: cam_off,
- }
- }
- pub fn update(
- &mut self, delta_time: f32,
- keys: &KeyboardState,
- camera: &mut Camera,
- world: &[&dyn Collidable]
- ) {
- let f = camera.forward();
- let forward = Vector3::new(f.x, 0.0, f.z).normalize();
- let r = camera.right_dir();
- let right = Vector3::new(r.x, 0.0, r.z).normalize();
- let mut dir = Vector3::zeros();
- //print!("Direction: {:?}\n", dir);
- if keys.is_scancode_pressed(sdl2::keyboard::Scancode::W) { dir += forward; }
- if keys.is_scancode_pressed(sdl2::keyboard::Scancode::S) { dir -= forward; }
- if keys.is_scancode_pressed(sdl2::keyboard::Scancode::A) { dir -= right; }
- if keys.is_scancode_pressed(sdl2::keyboard::Scancode::D) { dir += right; }
- if dir != Vector3::zeros() {
- dir = dir.normalize() * self.speed;
- }
- self.velocity.x = dir.x;
- self.velocity.z = dir.z;
- //self.velocity.y += self.gravity * delta_time;
- if self.on_ground && keys.is_scancode_pressed(sdl2::keyboard::Scancode::Space) {
- self.velocity.y = self.jump_speed;
- self.on_ground = false;
- }
- let current = self.body.position;
- let delta_pos = current + self.velocity * delta_time;
- let make_col = |pos: Vector3<f32>| Collider {
- min: pos - Vector3::new(0.5, 1.0, 0.5),
- max: pos + Vector3::new(0.5, 1.0, 0.5),
- };
- //print!("Current position: {:?}\n", current);
- let mut new_pos = current;
- for i in 0..3 {
- let mut test = new_pos;
- test[i] = delta_pos[i];
- let c = make_col(test);
- let hit = world.iter().any(|w| c.intersects(&w.collider()));
- //print!("Hit: {}\n", hit.clone());
- if !hit {
- new_pos[i] = delta_pos[i];
- //print!("No Hit\n");
- } else if i == 1 && self.velocity.y < 0.0 {
- // landed
- //print!("Hit ground\n");
- self.on_ground = true;
- self.velocity.y = 0.0;
- }
- }
- self.body.position = new_pos;
- let eye = self.body.position + self.camera_offset;
- camera.set_position(eye);
- }
- pub fn check_collision(&self, world: &[Box<dyn Collidable>]) -> bool {
- let c = self.collider();
- world.iter().any(|w| c.intersects(&w.collider()))
- }
- pub fn draw(
- &self,
- shader: &crate::shader::Shader,
- camera: &Camera,
- projection: &nalgebra::Matrix4<f32>,
- ) {
- shader.use_program();
- shader.set_mat4("model", &self.body.model_matrix());
- shader.set_mat4("view", &camera.get_view_matrix());
- shader.set_mat4("projection", projection);
- shader.set_vec3("objectColor", &self.body.color());
- shader.set_bool("useTexture", false);
- unsafe {
- gl::BindVertexArray(self.body.vao());
- gl::DrawArrays(gl::TRIANGLES, 0, self.body.vertex_count());
- }
- }
- }
- impl Collidable for Player {
- fn collider(&self) -> Collider {
- self.body.collider()
- }
- }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement