Add timer to line clearing

This commit is contained in:
Dendy 2023-10-07 20:38:27 +02:00
parent 1b0ab7c602
commit e281938578
2 changed files with 54 additions and 8 deletions

View File

@ -56,6 +56,7 @@ timer_left_das: Timer,
timer_right_arr: Timer, timer_right_arr: Timer,
timer_right_das: Timer, timer_right_das: Timer,
timer_gravity: Timer, timer_gravity: Timer,
timer_line_clear: Timer,
needs_reinit: bool = false, needs_reinit: bool = false,
@ -75,6 +76,7 @@ pub fn init(renderer: *Renderer.Renderer) Self {
.timer_right_arr = Timer.init(0.05), .timer_right_arr = Timer.init(0.05),
.timer_right_das = Timer.init(0.2), .timer_right_das = Timer.init(0.2),
.timer_gravity = Timer.init(0.3), .timer_gravity = Timer.init(0.3),
.timer_line_clear = Timer.init(1),
}; };
// Get a piece from the bag // Get a piece from the bag
@ -85,6 +87,10 @@ pub fn init(renderer: *Renderer.Renderer) Self {
// Main Game loop // Main Game loop
pub fn tick(self: *Self) State { 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 // TIMERS
// Dropping a piece // 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.*); self.renderer.render(self.*);

View File

@ -15,6 +15,7 @@ pub const buffer = 10;
cells: [nrows][ncolumns]Cell, cells: [nrows][ncolumns]Cell,
topped: bool = false, topped: bool = false,
lines_to_clear: [nrows]bool = .{false} ** nrows,
pub fn init() Self { pub fn init() Self {
var self = Self{ var self = Self{
@ -30,23 +31,44 @@ pub fn init() Self {
return self; return self;
} }
pub fn clearLines(self: *Self) u8 { pub fn updateLinesToClear(self: *Self) bool {
var ncleared: u8 = 0; var ret: bool = false;
// Look at each row
for (self.cells, 0..) |_, y| { for (self.cells, 0..) |_, y| {
// Look at each cell in the line
for (self.cells[y], 0..) |cell_x, x| { for (self.cells[y], 0..) |cell_x, x| {
if (cell_x.free) { if (cell_x.free) {
// It is free, this line isn't to be cleared
break; break;
} else { } else {
// Reached the end of the column? // Reached the end of the column?
if (x == self.cells[y].len - 1) { if (x == self.cells[y].len - 1) {
// Delete current row and bring the others down self.lines_to_clear[y] = true;
for (self.cells[1..y], 0..) |_, i| { ret = true;
self.cells[y - i] = self.cells[y - i - 1];
}
ncleared += 1;
} }
} }
} }
} }
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; return ncleared;
} }