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_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.*);

View File

@ -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;
}