Chandra-Game-Tetris
view release on metacpan or search on metacpan
lib/Chandra/Game/Tetris/Engine.pm view on Meta::CPAN
my $class = $cell ? "tetris-col filled block-$cell" : 'tetris-col';
$tr->add_child({
tag => 'td',
class => $class,
children => [{ tag => 'div' }],
});
}
}
return $html;
}
sub _lock_and_spawn {
my ($self) = @_;
my $grid = $self->grid;
my $current = $self->blocks->current;
$grid->lock_block(
$current->cells, $current->row, $current->col, $current->id
);
my $cleared = $grid->clear_lines;
$self->update_score($cleared);
if (!$self->spawn_next($current)) {
return {
game_over => 1,
grid => $self->render_grid,
score => $self->score,
lines => $self->lines,
level => $self->level,
};
}
my $next_html = $self->blocks->next->render->render;
return {
game_over => 0,
grid => $self->render_grid,
score => $self->score,
lines => $self->lines,
level => $self->level,
next_block => $next_html,
};
}
sub spawn_next {
my ($self) = @_;
my $blocks = $self->blocks;
my $block = $blocks->next;
$blocks->current($block);
$block->row(0);
$block->col(($self->grid->width / 2) - 2);
return $self->grid->is_valid(
$block->cells, $block->row, $block->col
);
}
sub reset_game {
my ($self) = @_;
$self->grid->reset;
$self->score(0);
$self->lines(0);
$self->level(1);
}
sub update_score {
my ($self, $cleared) = @_;
return unless $cleared;
my @points = (0, 100, 300, 500, 800);
my $pts = ($points[$cleared] // 800) * $self->level;
$self->score($self->score + $pts);
$self->lines($self->lines + $cleared);
$self->level(int($self->lines / 10) + 1);
}
sub rotate_cw {
my ($cells) = @_;
my $n = scalar @$cells;
my @r;
for my $row (0 .. $n - 1) {
for my $col (0 .. $n - 1) {
$r[$row][$col] = $cells->[$n - 1 - $col][$row];
}
}
return \@r;
}
sub css {
return q|
*, *::before, *::after {
box-sizing: border-box;
margin: 0;
padding: 0;
}
:root {
--background: rgb(20, 24, 27);
--color: rgb(240, 244, 247);
--cell: clamp(16px, min(calc((100vw - 160px) / 10), calc((100vh - 80px) / 18)), 40px);
--grid-w: calc(var(--cell) * 10);
--grid-h: calc(var(--cell) * 18);
--panel-w: calc(var(--cell) * 5);
--border: 1px solid rgb(40, 44, 47);
--cell-bg: rgb(30, 34, 37);
}
body {
background: var(--background);
min-height: 100vh;
display: flex;
align-items: center;
justify-content: center;
}
.wrapper {
display: flex;
flex-direction: column;
align-items: center;
gap: 0.5rem;
padding: 1rem;
}
.title {
color: var(--color);
font-family: monospace;
( run in 0.805 second using v1.01-cache-2.11-cpan-13bb782fe5a )