diff options
| author | tslil clingman <> | 2021-09-12 21:40:58 -0400 |
|---|---|---|
| committer | tslil clingman <> | 2021-09-12 21:40:58 -0400 |
| commit | d89f038b7a5eb42dd48d729d8808747d5cbc182b (patch) | |
| tree | 2f726aef25edaf1723e62ec99e19c425afa37cdf | |
| parent | b674e201cecf38ae719f76c0d159d8cbf00158ed (diff) | |
Walk bob and collision detection
| -rw-r--r-- | src/level.zig | 3 | ||||
| -rw-r--r-- | src/main.zig | 29 | ||||
| -rw-r--r-- | src/raycast.zig | 52 |
3 files changed, 64 insertions, 20 deletions
diff --git a/src/level.zig b/src/level.zig index 610eb7b..1d61a02 100644 --- a/src/level.zig +++ b/src/level.zig @@ -62,8 +62,7 @@ pub const Map = struct { } pub fn lookup(self: Map, x: i32, y: i32) Cell { - // live dangerously, no bounds check - std.debug.assert(x >= 0 and y >= 0); // compiler hint? + // std.debug.assert(x >= 0 and y >= 0); // would this work as a compiler hint? return self.cells.items[@intCast(u32, y) * self.width + @intCast(u32, x)]; } }; diff --git a/src/main.zig b/src/main.zig index c44b5e6..ec47f86 100644 --- a/src/main.zig +++ b/src/main.zig @@ -133,24 +133,33 @@ pub fn main() !void { if (isKeyPressed(.R)) player.ang += rotation; if (isKeyPressed(.T)) player.ang -= rotation; + const cos = std.math.cos(player.ang); + const sin = std.math.sin(player.ang); + player.acc_x = 0; player.acc_y = 0; - const acc_mag = 50; + const acc_mag = 30; if (isKeyPressed(.Right)) { - player.acc_x += std.math.cos(player.ang - PI / 2.0) * acc_mag; - player.acc_y += std.math.sin(player.ang - PI / 2.0) * acc_mag; + player.acc_x += sin; + player.acc_y -= cos; } if (isKeyPressed(.Left)) { - player.acc_x -= std.math.cos(player.ang - PI / 2.0) * acc_mag; - player.acc_y -= std.math.sin(player.ang - PI / 2.0) * acc_mag; + player.acc_x -= sin; + player.acc_y += cos; } if (isKeyPressed(.Up) or isKeyPressed(.F)) { - player.acc_x += std.math.cos(player.ang) * acc_mag; - player.acc_y += std.math.sin(player.ang) * acc_mag; + player.acc_x += cos; + player.acc_y += sin; } if (isKeyPressed(.Down) or isKeyPressed(.S)) { - player.acc_x -= std.math.cos(player.ang) * acc_mag; - player.acc_y -= std.math.sin(player.ang) * acc_mag; + player.acc_x -= cos; + player.acc_y -= sin; + } + // normalise + const a = std.math.sqrt(player.acc_x * player.acc_x + player.acc_y * player.acc_y); + if (a > 0) { + player.acc_x *= acc_mag / a; + player.acc_y *= acc_mag / a; } // First the background @@ -177,6 +186,6 @@ pub fn main() !void { window.display(); - player.tick(); + player.tick(map); } } 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( |
