Separate and improve player movement

This commit is contained in:
2025-11-30 22:45:29 +01:00
parent 4d61b14052
commit b3b6b6c30a
3 changed files with 158 additions and 98 deletions

135
src/Player.zig Normal file
View File

@@ -0,0 +1,135 @@
const Player = @This();
const std = @import("std");
const glfw = @import("zglfw");
const math = @import("math.zig");
const Vector2 = math.Vector2;
const Vector3 = math.Vector3;
const AxisState = enum {
none,
positive,
negative,
both_positive,
both_negative,
pub fn getComponent(self: AxisState) f32 {
return switch (self) {
.none => 0,
.positive, .both_positive => 1,
.negative, .both_negative => -1,
};
}
};
const Axis = struct {
state: AxisState = .none,
positive_key: glfw.Key,
negative_key: glfw.Key,
pub fn init(positive_key: glfw.Key, negative_key: glfw.Key) Axis {
return .{
.positive_key = positive_key,
.negative_key = negative_key,
};
}
pub fn onKeyDown(self: *Axis, key_code: glfw.Key) void {
if (key_code == self.positive_key) {
switch (self.state) {
.none => self.state = .positive,
.negative => self.state = .both_positive,
else => unreachable,
}
} else if (key_code == self.negative_key) {
switch (self.state) {
.none => self.state = .negative,
.positive => self.state = .both_negative,
else => unreachable,
}
}
}
pub fn onKeyUp(self: *Axis, key_code: glfw.Key) void {
if (key_code == self.positive_key) {
switch (self.state) {
.positive => self.state = .none,
.both_positive, .both_negative => self.state = .negative,
else => unreachable,
}
} else if (key_code == self.negative_key) {
switch (self.state) {
.negative => self.state = .none,
.both_positive, .both_negative => self.state = .positive,
else => unreachable,
}
}
}
pub fn getComponent(self: Axis) f32 {
return self.state.getComponent();
}
};
position: Vector3,
pitch_rad: f32,
yaw_rad: f32,
x_input: Axis = .init(.d, .a),
y_input: Axis = .init(.w, .s),
z_input: Axis = .init(.space, .left_shift),
mouse_sensitivity: f32 = 0.002,
vertical_fov_deg: f32 = 80,
pub const camera_height = 1.62;
pub const horizontal_speed = 11.0;
pub const vertical_speed = 7.49;
pub const min_pitch_rad = -0.5 * std.math.pi;
pub const max_pitch_rad = 0.5 * std.math.pi;
pub fn init(position: Vector3, pitch_rad: f32, yaw_rad: f32) Player {
return .{
.position = position,
.pitch_rad = pitch_rad,
.yaw_rad = yaw_rad,
};
}
pub fn onKeyDown(self: *Player, key: glfw.Key) void {
self.x_input.onKeyDown(key);
self.y_input.onKeyDown(key);
self.z_input.onKeyDown(key);
}
pub fn onKeyUp(self: *Player, key: glfw.Key) void {
self.x_input.onKeyUp(key);
self.y_input.onKeyUp(key);
self.z_input.onKeyUp(key);
}
pub fn onMouseMove(self: *Player, dx: f32, dy: f32) void {
self.pitch_rad = std.math.clamp(self.pitch_rad - dy * self.mouse_sensitivity, min_pitch_rad, max_pitch_rad);
self.yaw_rad = @mod(self.yaw_rad - dx * self.mouse_sensitivity, std.math.tau);
}
pub fn update(self: *Player, dt: f32) void {
var horizontal_input_vector = Vector2
.init(self.x_input.getComponent(), self.y_input.getComponent())
.rotate(self.yaw_rad);
const horizontal_input_vector_len_squared = horizontal_input_vector.lenSquared();
if (horizontal_input_vector_len_squared > 1) {
horizontal_input_vector = horizontal_input_vector.divScalar(horizontal_input_vector_len_squared);
}
const vertical_input_vector = self.z_input.getComponent();
const horizontal_velocity = horizontal_input_vector.mulScalar(horizontal_speed);
const vertical_velocity = vertical_input_vector * vertical_speed;
const displacement = horizontal_velocity.asVector3(vertical_velocity).mulScalar(dt);
self.position = Vector3.add(self.position, displacement);
}