Separate and improve player movement
This commit is contained in:
135
src/Player.zig
Normal file
135
src/Player.zig
Normal 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);
|
||||
}
|
||||
Reference in New Issue
Block a user