From e2819385781fb26188b7560fb325aea62f454e7d Mon Sep 17 00:00:00 2001 From: Dendy Faist Date: Sat, 7 Oct 2023 20:38:27 +0200 Subject: [PATCH] Add timer to line clearing --- src/Game.zig | 26 +++++++++++++++++++++++++- src/Game/Grid.zig | 36 +++++++++++++++++++++++++++++------- 2 files changed, 54 insertions(+), 8 deletions(-) diff --git a/src/Game.zig b/src/Game.zig index 68f0e22..0dbd808 100644 --- a/src/Game.zig +++ b/src/Game.zig @@ -56,6 +56,7 @@ timer_left_das: Timer, timer_right_arr: Timer, timer_right_das: Timer, timer_gravity: Timer, +timer_line_clear: Timer, needs_reinit: bool = false, @@ -75,6 +76,7 @@ pub fn init(renderer: *Renderer.Renderer) Self { .timer_right_arr = Timer.init(0.05), .timer_right_das = Timer.init(0.2), .timer_gravity = Timer.init(0.3), + .timer_line_clear = Timer.init(1), }; // Get a piece from the bag @@ -85,6 +87,10 @@ pub fn init(renderer: *Renderer.Renderer) Self { // Main Game loop pub fn tick(self: *Self) State { + if (self.timer_line_clear.started and !self.timer_line_clear.finished()) { + self.renderer.render(self.*); + return self.state; + } // TIMERS // Dropping a piece @@ -209,7 +215,25 @@ pub fn tick(self: *Self) State { } } - self.score += self.grid.clearLines(); + // Check for empty lines. If there are, then start the clearing sequence + if (!self.timer_line_clear.started) { + if (self.grid.updateLinesToClear()) { + self.timer_line_clear.start(); + } + } + // Don't go and clear them until the timer has finished + else if (self.timer_line_clear.finished()) { + const clear_score = self.grid.clearLines(); + if (clear_score > 0) { + self.timer_line_clear.stop(); + self.score += clear_score; + } else { + std.debug.print("WARNING: Clear line timer stopped but there was nothign to clear. This situation isn't valid\n", .{}); + } + } + // NOTE: If for some reason game doesn't stop and another line has been cleared + // before the timer reached the end, that line will be processed right after + // the timer stops. Behaviour shouldn't get any funkier than that. self.renderer.render(self.*); diff --git a/src/Game/Grid.zig b/src/Game/Grid.zig index e71f1a4..5611afc 100644 --- a/src/Game/Grid.zig +++ b/src/Game/Grid.zig @@ -15,6 +15,7 @@ pub const buffer = 10; cells: [nrows][ncolumns]Cell, topped: bool = false, +lines_to_clear: [nrows]bool = .{false} ** nrows, pub fn init() Self { var self = Self{ @@ -30,23 +31,44 @@ pub fn init() Self { return self; } -pub fn clearLines(self: *Self) u8 { - var ncleared: u8 = 0; +pub fn updateLinesToClear(self: *Self) bool { + var ret: bool = false; + + // Look at each row for (self.cells, 0..) |_, y| { + // Look at each cell in the line for (self.cells[y], 0..) |cell_x, x| { if (cell_x.free) { + // It is free, this line isn't to be cleared break; } else { // Reached the end of the column? if (x == self.cells[y].len - 1) { - // Delete current row and bring the others down - for (self.cells[1..y], 0..) |_, i| { - self.cells[y - i] = self.cells[y - i - 1]; - } - ncleared += 1; + self.lines_to_clear[y] = true; + ret = true; } } } } + + return ret; +} + +pub fn clearLines(self: *Self) u8 { + var ncleared: u8 = 0; + + // Go line by line, checking if any of them needs to be cleared + for (self.lines_to_clear, 0..) |_, y| { + if (self.lines_to_clear[y]) { + // Delete current row and bring the others down + for (self.cells[1..y], 0..) |_, i| { + self.cells[y - i] = self.cells[y - i - 1]; + } + ncleared += 1; + } + } + + self.lines_to_clear = .{false} ** nrows; + return ncleared; }