aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/brothers.zig52
-rw-r--r--src/game.zig15
-rw-r--r--src/main.zig29
3 files changed, 76 insertions, 20 deletions
diff --git a/src/brothers.zig b/src/brothers.zig
index b221ddc..cf78988 100644
--- a/src/brothers.zig
+++ b/src/brothers.zig
@@ -8,6 +8,8 @@ pub const Side = enum(u1) {
const startingX = [2]f64{ 15, 60 };
const colors = [2]spoon.Attribute.Colour{ .blue, .red };
+const leftLimit = [2]f64{ 1, 40 };
+const rightLimit = [2]f64{ 33, 74 }; // (38, 79) minus a brother's width
pub const Brother = struct {
side: Side,
@@ -15,15 +17,7 @@ pub const Brother = struct {
y: f64,
dx: f64,
dy: f64,
- pub fn reset(self: *Brother, side: ?Side) void {
- if (side) |s| {
- self.side = s;
- }
- self.x = startingX[@enumToInt(self.side)];
- self.y = 17;
- self.dx = 0;
- self.dy = 0;
- }
+ moveDuration: u64,
pub fn draw(self: Brother, rc: *spoon.Term.RenderContext) !void {
try rc.setAttribute(.{ .fg = colors[@enumToInt(self.side)] });
var iter = std.mem.split(u8, brother, "\n");
@@ -34,6 +28,46 @@ pub const Brother = struct {
_ = try rc.buffer.writer().write(line);
}
}
+ pub fn moveLeft(self: *Brother) void {
+ self.dx -= 5 / (1000 / 60.0);
+ self.moveDuration = 24;
+ }
+ pub fn moveRight(self: *Brother) void {
+ self.dx += 5 / (1000 / 60.0);
+ self.moveDuration = 24;
+ }
+ pub fn step(self: *Brother) void {
+ const x = self.x + self.dx;
+ const ll = leftLimit[@enumToInt(self.side)];
+ const rl = rightLimit[@enumToInt(self.side)];
+ if (x < ll) {
+ self.x = ll;
+ self.dx = 0;
+ self.moveDuration = 0;
+ } else if (x > rl) {
+ self.x = rl;
+ self.dx = 0;
+ self.moveDuration = 0;
+ } else {
+ self.x = x;
+ if (self.moveDuration > 0) {
+ self.moveDuration -= 1;
+ if (self.moveDuration == 0) {
+ self.dx = 0;
+ }
+ }
+ }
+ }
+ pub fn reset(self: *Brother, side: ?Side) void {
+ if (side) |s| {
+ self.side = s;
+ }
+ self.x = startingX[@enumToInt(self.side)];
+ self.y = 17;
+ self.dx = 0;
+ self.dy = 0;
+ self.moveDuration = 0;
+ }
};
const brother =
diff --git a/src/game.zig b/src/game.zig
index fc64001..97c2c80 100644
--- a/src/game.zig
+++ b/src/game.zig
@@ -6,17 +6,28 @@ const playfield = @import("playfield.zig");
pub const Game = struct {
brothers: [2]brothers.Brother = undefined,
- character: ?brothers.Side = undefined,
+ side: brothers.Side = undefined,
pub fn draw(self: Game, rc: *spoon.Term.RenderContext) !void {
try playfield.draw(rc);
try self.brothers[0].draw(rc);
try self.brothers[1].draw(rc);
}
- pub fn reset(self: *Game) void {
+ pub fn moveLeft(self: *Game) void {
+ self.brothers[@enumToInt(self.side)].moveLeft();
+ }
+ pub fn moveRight(self: *Game) void {
+ self.brothers[@enumToInt(self.side)].moveRight();
+ }
+ pub fn reset(self: *Game, side: brothers.Side) void {
+ self.side = side;
self.resetRound();
}
pub fn resetRound(self: *Game) void {
self.brothers[0].reset(brothers.Side.left);
self.brothers[1].reset(brothers.Side.right);
}
+ pub fn step(self: *Game) void {
+ self.brothers[0].step();
+ self.brothers[1].step();
+ }
};
diff --git a/src/main.zig b/src/main.zig
index cec8688..120e926 100644
--- a/src/main.zig
+++ b/src/main.zig
@@ -33,21 +33,32 @@ pub fn main() !void {
try term.fetchSize();
try term.setWindowTitle("Grenade Brothers", .{});
- gs.reset();
+ gs.reset(.left);
try renderAll();
var buf: [16]u8 = undefined;
while (!done) {
- _ = try std.os.poll(&fds, 100);
-
- const read = try term.readInput(&buf);
- var it = spoon.inputParser(buf[0..read]);
- while (it.next()) |in| {
- if (in.eqlDescription("escape") or in.eqlDescription("q")) {
- done = true;
- break;
+ // TODO We need to measure how long it took before a key was hit so that we can adjust the timeout on the next loop
+ // otherwise we will get inconsistent ticks for movement steps
+ const timeout = try std.os.poll(&fds, @floatToInt(u64, 1000 / 60.0));
+
+ if (timeout > 0) { // if timeout if not 0 then some fds we are polling have events for us
+ const read = try term.readInput(&buf);
+ var it = spoon.inputParser(buf[0..read]);
+ while (it.next()) |in| {
+ if (in.eqlDescription("escape") or in.eqlDescription("q")) {
+ done = true;
+ break;
+ } else if (in.eqlDescription("arrow-left") or in.eqlDescription("a")) {
+ gs.moveLeft();
+ } else if (in.eqlDescription("arrow-right") or in.eqlDescription("d")) {
+ gs.moveRight();
+ }
}
+ } else {
+ gs.step();
}
+ try renderAll();
}
}