Advertisement
Guest User

Untitled

a guest
May 4th, 2025
11
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Rust 4.32 KB | None | 0 0
  1. use crate::{
  2.     capsule::Capsule,
  3.     collision::{Collidable, Collider},
  4.     camera::Camera,
  5.     renderable::Renderable,
  6. };
  7. use nalgebra::Vector3;
  8. use sdl2::keyboard::KeyboardState;
  9.  
  10. pub struct Player {
  11.     pub body: Capsule,
  12.     pub velocity: Vector3<f32>,
  13.     pub speed: f32,
  14.     pub jump_speed: f32,
  15.     pub gravity: f32,
  16.     pub on_ground: bool,
  17.     pub camera_offset: Vector3<f32>,
  18. }
  19.  
  20. impl Player {
  21.     pub fn new(spawn_pos: Vector3<f32>, eye_height: f32) -> Player {
  22.         let scale = Vector3::new(1.0, 2.0, 1.0);
  23.         let half_h = 1.0 * scale.y;
  24.  
  25.         let center_y = spawn_pos.y + half_h;
  26.  
  27.         let body = Capsule::new(
  28.             Vector3::new(spawn_pos.x, center_y, spawn_pos.z),
  29.             Vector3::zeros(),
  30.             scale,
  31.             Vector3::new(0.2, 0.4, 1.0),
  32.             16, 8,
  33.         );
  34.  
  35.         let cam_off = Vector3::new(0.0, eye_height - half_h, 0.0);
  36.  
  37.         Player {
  38.             body,
  39.             velocity: Vector3::zeros(),
  40.             speed: 6.0,
  41.             jump_speed: 8.0,
  42.             gravity: -9.81,
  43.             on_ground: false,
  44.             camera_offset: cam_off,
  45.         }
  46.     }
  47.  
  48.     pub fn update(
  49.         &mut self, delta_time: f32,
  50.         keys: &KeyboardState,
  51.         camera: &mut Camera,
  52.         world: &[&dyn Collidable]
  53.     ) {
  54.         let f = camera.forward();
  55.         let forward = Vector3::new(f.x, 0.0, f.z).normalize();
  56.         let r = camera.right_dir();
  57.         let right = Vector3::new(r.x, 0.0, r.z).normalize();
  58.  
  59.         let mut dir = Vector3::zeros();
  60.  
  61.         //print!("Direction: {:?}\n", dir);
  62.  
  63.         if keys.is_scancode_pressed(sdl2::keyboard::Scancode::W) { dir += forward; }
  64.         if keys.is_scancode_pressed(sdl2::keyboard::Scancode::S) { dir -= forward; }
  65.         if keys.is_scancode_pressed(sdl2::keyboard::Scancode::A) { dir -= right; }
  66.         if keys.is_scancode_pressed(sdl2::keyboard::Scancode::D) { dir += right; }
  67.  
  68.         if dir != Vector3::zeros() {
  69.             dir = dir.normalize() * self.speed;
  70.         }
  71.  
  72.         self.velocity.x = dir.x;
  73.         self.velocity.z = dir.z;
  74.         //self.velocity.y += self.gravity * delta_time;
  75.  
  76.         if self.on_ground && keys.is_scancode_pressed(sdl2::keyboard::Scancode::Space) {
  77.             self.velocity.y = self.jump_speed;
  78.             self.on_ground = false;
  79.         }
  80.  
  81.         let current = self.body.position;
  82.         let delta_pos = current + self.velocity * delta_time;
  83.  
  84.         let make_col = |pos: Vector3<f32>| Collider {
  85.             min: pos - Vector3::new(0.5, 1.0, 0.5),
  86.             max: pos + Vector3::new(0.5, 1.0, 0.5),
  87.         };
  88.  
  89.         //print!("Current position: {:?}\n", current);
  90.  
  91.         let mut new_pos = current;
  92.         for i in 0..3 {
  93.             let mut test = new_pos;
  94.             test[i] = delta_pos[i];
  95.             let c = make_col(test);
  96.             let hit = world.iter().any(|w| c.intersects(&w.collider()));
  97.             //print!("Hit: {}\n", hit.clone());
  98.             if !hit {
  99.                 new_pos[i] = delta_pos[i];
  100.                 //print!("No Hit\n");
  101.             } else if i == 1 && self.velocity.y < 0.0 {
  102.                 // landed
  103.                 //print!("Hit ground\n");
  104.                 self.on_ground = true;
  105.                 self.velocity.y = 0.0;
  106.             }
  107.         }
  108.         self.body.position = new_pos;
  109.  
  110.         let eye = self.body.position + self.camera_offset;
  111.         camera.set_position(eye);
  112.     }
  113.  
  114.     pub fn check_collision(&self, world: &[Box<dyn Collidable>]) -> bool {
  115.         let c = self.collider();
  116.         world.iter().any(|w| c.intersects(&w.collider()))
  117.     }
  118.  
  119.     pub fn draw(
  120.         &self,
  121.         shader: &crate::shader::Shader,
  122.         camera: &Camera,
  123.         projection: &nalgebra::Matrix4<f32>,
  124.     ) {
  125.         shader.use_program();
  126.         shader.set_mat4("model", &self.body.model_matrix());
  127.         shader.set_mat4("view", &camera.get_view_matrix());
  128.         shader.set_mat4("projection", projection);
  129.         shader.set_vec3("objectColor", &self.body.color());
  130.         shader.set_bool("useTexture", false);
  131.  
  132.         unsafe {
  133.             gl::BindVertexArray(self.body.vao());
  134.             gl::DrawArrays(gl::TRIANGLES, 0, self.body.vertex_count());
  135.         }
  136.     }
  137. }
  138.  
  139. impl Collidable for Player {
  140.     fn collider(&self) -> Collider {
  141.         self.body.collider()
  142.     }
  143. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement