diff options
author | heav <hheav3@gmail.com> | 2023-03-26 10:33:29 +0000 |
---|---|---|
committer | heav <hheav3@gmail.com> | 2023-03-26 10:33:29 +0000 |
commit | 9ee7aa26f4e1a9f7cbc29b43fbfd0e698061bd6e (patch) | |
tree | 90b42a0fe1bc1d03bdcac0498f28b41f658e57bc | |
parent | 269a8f2fe621ed281b4115eed963db9815eb1eef (diff) |
add hold
-rw-r--r-- | game/gfx.lua | 68 | ||||
-rw-r--r-- | game/init.lua | 23 | ||||
-rw-r--r-- | game/polyomino.lua | 16 | ||||
-rw-r--r-- | heav_optimal_shapes.lua | 32 |
4 files changed, 119 insertions, 20 deletions
diff --git a/game/gfx.lua b/game/gfx.lua index e3db203..0f64ddc 100644 --- a/game/gfx.lua +++ b/game/gfx.lua @@ -1,5 +1,6 @@ local evloop = require "evloop" local viewport = require "viewport" +local tetrominoes = require "game/tetrominoes" local M = {} M.__index = M @@ -11,12 +12,12 @@ end local colors = { ["tetr.Z"] = {1, 0.2, 0.2}, - ["tetr.I"] = {1, 0.7, 0.2}, - ["tetr.J"] = {1, 1, 0.2}, - ["tetr.L"] = {0.2, 1, 0.2}, - ["tetr.O"] = {0.2, 0.2, 1}, - ["tetr.S"] = {0.5, 0.2, 0.7}, - ["tetr.T"] = {0.7, 0.2, 1}, + ["tetr.I"] = {0.2, 1, 1}, + ["tetr.J"] = {0.2, 0.2, 1}, + ["tetr.L"] = {1, 0.5, 0.2}, + ["tetr.O"] = {1, 1, 0.2}, + ["tetr.S"] = {0.2, 1, 0.2}, + ["tetr.T"] = {1, 0.2, 1}, } function M:field_dimensions() @@ -40,20 +41,62 @@ function M:field_dimensions() return block_size, x, y, w, h end +function M:draw_square(block, x, y, block_size) + if colors[block] then + love.graphics.setColor(unpack(colors[block])) + else + love.graphics.setColor(1, 1, 1) + end + love.graphics.rectangle("fill", x, y, block_size, block_size) +end + function M:draw_block(block, line, column) local block_size, field_x, field_y, _, field_h = self:field_dimensions() local x = field_x + (column - 1) * block_size local y = field_y + field_h - line * block_size - if block then - if colors[block] then - love.graphics.setColor(unpack(colors[block])) - else - love.graphics.setColor(1, 1, 1) + if block then self:draw_square(block, x, y, block_size) end +end + +function M:draw_tetromino(tetromino, x, y, block_size, trim_margins) + for yy, line in pairs(tetromino.cells) do + for xx, cell in pairs(line) do + local xxx = xx + local yyy = yy + yyy = tetromino.size - yyy + 1 + if trim_margins then + xxx = xxx - tetromino.left_side + 1 + yyy = yyy - (tetromino.size-tetromino.top) + end + M:draw_square(cell, x + (xxx-1)*block_size, y + (yyy-1)*block_size, block_size) end - love.graphics.rectangle("fill", x, y, block_size, block_size) end end +local function debug_mark(x,y,...) + love.graphics.setColor(...) + love.graphics.rectangle("fill",x-1,y-1,3,3) +end + +function M:draw_hold() + local block_size, field_x, field_y, field_w, field_h = self:field_dimensions() + local hold_x = field_x + field_w + block_size + local hold_y = field_y + local margin = block_size/2 + love.graphics.setColor(0, 0, 0) + love.graphics.rectangle("fill", hold_x, hold_y, block_size*1.5 + margin, block_size*1.5 + margin) + if not self.game.can_hold then + love.graphics.setColor(0.5, 0.5, 0.5, 0.5) + love.graphics.rectangle("fill", hold_x, hold_y, block_size*1.5 + margin, block_size*1.5 + margin) + end + if not self.game.hold then return end + local piece = self.game.hold + local piece_dim = math.max(piece.width, piece.height) + local piece_scale = 3/math.max(piece_dim, 3) + local piece_x = hold_x + margin/2 + (3-piece.width*piece_scale)/2 * block_size/2 + local piece_y = hold_y + margin/2 + (3-piece.height*piece_scale)/2 * block_size/2 + self:draw_tetromino(self.game.hold, piece_x, piece_y, piece_scale * block_size/2, true) +end + function M:draw_piece() local piece = self.game.piece if not piece then return end @@ -86,6 +129,7 @@ function M:draw(dt) love.graphics.rectangle("fill", 0, 0, 1920, 1080) self:draw_field() self:draw_piece() + self:draw_hold() end function M:loop() diff --git a/game/init.lua b/game/init.lua index ca071d1..4fb9928 100644 --- a/game/init.lua +++ b/game/init.lua @@ -10,6 +10,8 @@ function M.new(params) local new = setmetatable({}, M) new.params = params new.field = playfield.new(params.lines or 20, params.columns or 10) + new.hold = false + new.can_hold = true new.gfx = gfx.new(new) new.gravity_delay = 0.5 return new @@ -36,6 +38,19 @@ function M:input_loop() elseif key == "space" then repeat until not self.piece:move(-1, 0) self.piece:place() + elseif key == "c" then + if not self.can_hold then goto bypass end + if not self.hold then + self.hold = self.piece.poly + self:next_piece() + else + local tmp = self.hold + self.hold = self.piece.poly + self.piece = tmp:drop(self.field) + + end + self.can_hold = false + ::bypass:: end end @@ -45,18 +60,22 @@ function M:input_loop() end local pieces = { - tetrominoes.i, + --[[tetrominoes.i, tetrominoes.j, tetrominoes.l, tetrominoes.o, tetrominoes.s, tetrominoes.t, - tetrominoes.z, + tetrominoes.z,]] + tetrominoes.i, + tetrominoes.o, + tetrominoes.j } function M:next_piece() -- TODO: interface with configurable random system (it should implement -- seeds, bags) + self.can_hold = true self.piece = pieces[love.math.random(#pieces)]:drop(self.field) return self.piece and true or false end diff --git a/game/polyomino.lua b/game/polyomino.lua index 933a4fd..4294c7f 100644 --- a/game/polyomino.lua +++ b/game/polyomino.lua @@ -20,18 +20,22 @@ function M.def(name, shape) end table.insert(new.cells, 1, line) end - + new.bottom = new.size + new.top = 1 + new.left_side = new.size + new.right_side = 1 for line = 1, new.size do for column = 1, new.size do if new.cells[line][column] then - new.bottom = line + if new.bottom > line then new.bottom = line end + if new.right_side < column then new.right_side = column end + if new.top < line then new.top = line end + if new.left_side > column then new.left_side = column end end end - if new.bottom then - break - end end - + new.height = new.top - new.bottom + 1 + new.width = new.right_side - new.left_side + 1 return new end diff --git a/heav_optimal_shapes.lua b/heav_optimal_shapes.lua new file mode 100644 index 0000000..784ba8e --- /dev/null +++ b/heav_optimal_shapes.lua @@ -0,0 +1,32 @@ +local poly = require "polyomino" + +local M = {} +M.__index = M + +M.spite_shape = poly.def("heav.spite_shape", [[ + #.# + .#.# + #.#. + .#.# +]]) + +M.heav = poly.def("heav.heav", [[ + .#.. + .### + ###. + ..#. +]]) + +M.colon = poly.def("heav.colon", [[ + .#. + ... + .#. +]]) + +M.semicolon = poly.def("heav.semicolon", [[ + .#. + ... + ##. +]]) + +return M |