aboutsummaryrefslogtreecommitdiff
path: root/src/raycast.zig
diff options
context:
space:
mode:
authortslil clingman <>2021-09-12 21:40:58 -0400
committertslil clingman <>2021-09-12 21:40:58 -0400
commitd89f038b7a5eb42dd48d729d8808747d5cbc182b (patch)
tree2f726aef25edaf1723e62ec99e19c425afa37cdf /src/raycast.zig
parentb674e201cecf38ae719f76c0d159d8cbf00158ed (diff)
Walk bob and collision detection
Diffstat (limited to 'src/raycast.zig')
-rw-r--r--src/raycast.zig52
1 files changed, 44 insertions, 8 deletions
diff --git a/src/raycast.zig b/src/raycast.zig
index 77a9ef0..6082b74 100644
--- a/src/raycast.zig
+++ b/src/raycast.zig
@@ -80,6 +80,8 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type {
height: f32 = 2.0 * (1.8 / 2.5), // TODO
z_buffer: std.BoundedArray(f32, PlanePixels),
+ anim_step: f32 = 0,
+
// standing still at the given location, looking in direction ang
pub fn new(pos_x: f32, pos_y: f32, ang: f32) !@This() {
const infs = [_]f32{std.math.inf(f32)} ** PlanePixels;
@@ -92,21 +94,55 @@ pub fn Player(PlaneWidth: f32, PlaneHeight: f32) type {
};
}
- pub fn tick(self: *@This()) void {
+ pub fn tick(self: *@This(), map: level.Map) void {
const dt = 1 / 30.0;
const v_min = 0.8;
- const v_decay = 1.25;
+ const v_decay = 1 / 1.25;
+
+ var next_x = self.pos_x + self.vel_x * dt;
+ var next_y = self.pos_y + self.vel_y * dt;
- self.pos_x += self.vel_x * dt;
- self.pos_y += self.vel_y * dt;
+ // Collision detection
+ const min_dist: f32 = 0.1;
+ const fx = std.math.floor(self.pos_x);
+ const fy = std.math.floor(self.pos_y);
+ const ix = @floatToInt(i32, fx);
+ const iy = @floatToInt(i32, fy);
+ const nix = @floatToInt(i32, std.math.floor(next_x + if (self.vel_x > 0) min_dist else -min_dist));
+ const niy = @floatToInt(i32, std.math.floor(next_y + if (self.vel_y > 0) min_dist else -min_dist));
- self.vel_x /= v_decay;
- if (std.math.fabs(self.vel_x) < v_min) self.vel_x = 0;
- self.vel_y /= v_decay;
- if (std.math.fabs(self.vel_y) < v_min) self.vel_y = 0;
+ if (!map.inBounds(nix, iy) or map.lookup(nix, iy).height > 0) {
+ next_x = fx + if (self.vel_x > 0) 1 - min_dist else min_dist;
+ self.vel_x = 0;
+ self.acc_x = 0;
+ }
+
+ if (!map.inBounds(ix, niy) or map.lookup(ix, niy).height > 0) {
+ next_y = fy + if (self.vel_y > 0) 1 - min_dist else min_dist;
+ self.vel_y = 0;
+ self.acc_y = 0;
+ }
+ // Update position
+ self.pos_x = next_x;
+ self.pos_y = next_y;
+
+ // Update velocity
self.vel_x += self.acc_x * dt;
self.vel_y += self.acc_y * dt;
+
+ const vd = v_decay * std.math.sqrt(self.vel_x * self.vel_x + self.vel_y * self.vel_y);
+ if (vd < v_min) {
+ self.vel_x = 0;
+ self.vel_y = 0;
+ } else {
+ // If we're moving update our animation state
+ self.anim_step += 1;
+ self.height -= std.math.sin(self.anim_step / 10 * std.math.pi) * 0.015;
+
+ self.vel_x *= v_decay;
+ self.vel_y *= v_decay;
+ }
}
pub fn renderWorld(