From a9c30f6236af36f6c428b0b10dd4d48a21c70733 Mon Sep 17 00:00:00 2001 From: Julien Dessaux Date: Sun, 14 Aug 2022 15:36:59 +0200 Subject: Implement left and right movements --- src/brothers.zig | 52 +++++++++++++++++++++++++++++++++++++++++++--------- src/game.zig | 15 +++++++++++++-- src/main.zig | 29 ++++++++++++++++++++--------- 3 files changed, 76 insertions(+), 20 deletions(-) (limited to 'src') 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(); } } -- cgit v1.2.3