5 new modes + ASC - 3 aren't even ***ris!
parent
44d0605fb7
commit
484c8adff3
|
@ -0,0 +1,15 @@
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local SurvivalA3Game = require 'tetris.modes.survival_a3'
|
||||||
|
|
||||||
|
local A3Minus = SurvivalA3Game:extend()
|
||||||
|
|
||||||
|
A3Minus.name = "Survival A3-"
|
||||||
|
A3Minus.hash = "A3Minus"
|
||||||
|
A3Minus.tagline = "A training version of Survival A3."
|
||||||
|
|
||||||
|
function A3Minus:initialize(ruleset)
|
||||||
|
self.torikan_time = math.huge
|
||||||
|
GameMode.initialize(self, ruleset)
|
||||||
|
end
|
||||||
|
|
||||||
|
return A3Minus
|
File diff suppressed because it is too large
Load Diff
|
@ -0,0 +1,293 @@
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local Grid = require 'tetris.components.grid'
|
||||||
|
|
||||||
|
local Minesweeper = GameMode:extend()
|
||||||
|
|
||||||
|
Minesweeper.name = "Minesweeper"
|
||||||
|
Minesweeper.hash = "Minesweeper"
|
||||||
|
Minesweeper.tagline = "Avoid the exploding mines!"
|
||||||
|
|
||||||
|
local width = 15
|
||||||
|
local height = 15
|
||||||
|
|
||||||
|
function Minesweeper:new()
|
||||||
|
self.super:new()
|
||||||
|
self:initializeGrid()
|
||||||
|
self.menu_state = 1
|
||||||
|
self.mines = {}
|
||||||
|
self.cursor = {x=1, y=1}
|
||||||
|
self.first_move = true
|
||||||
|
self.ready_frames = 1
|
||||||
|
self.next_queue_length = 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:isMine(x, y)
|
||||||
|
for _, mine in pairs(self.mines) do
|
||||||
|
if mine.x == x and mine.y == y then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:initializeGrid()
|
||||||
|
self.grid = Grid(width, height + 4)
|
||||||
|
self.flags = math.floor(0.15 * width * height)
|
||||||
|
self.chosen_colour = ({ "R", "O", "Y", "G", "C", "B", "M" })[math.random(7)]
|
||||||
|
for y = 1, height do
|
||||||
|
for x = 1, width do
|
||||||
|
self.grid.grid[y+4][x] = { skin = "2tie", colour = self.chosen_colour }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:initializeMines(sel_x, sel_y)
|
||||||
|
for i = 1, self.flags do
|
||||||
|
local x, y
|
||||||
|
repeat
|
||||||
|
x = math.random(1, width)
|
||||||
|
y = math.random(1, height)
|
||||||
|
until not (self:isMine(x, y) or (sel_x == x and sel_y == y))
|
||||||
|
table.insert(self.mines, {x=x, y=y})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:advanceOneFrame(inputs, ruleset)
|
||||||
|
if self.menu_state ~= 0 then
|
||||||
|
self:menuLoop(inputs)
|
||||||
|
return false
|
||||||
|
elseif self.game_over or self.completed or self.ready_frames > 1 then
|
||||||
|
return true
|
||||||
|
else
|
||||||
|
self:mainGameLoop(inputs)
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:menuLoop(inputs)
|
||||||
|
if not self.prev_inputs.right and inputs.right then
|
||||||
|
if self.menu_state == 1 then
|
||||||
|
width = math.min(width + 1, 28)
|
||||||
|
else
|
||||||
|
height = math.min(height + 1, 22)
|
||||||
|
end
|
||||||
|
self:initializeGrid()
|
||||||
|
elseif not self.prev_inputs.left and inputs.left then
|
||||||
|
if self.menu_state == 1 then
|
||||||
|
width = math.max(width - 1, 8)
|
||||||
|
else
|
||||||
|
height = math.max(height - 1, 8)
|
||||||
|
end
|
||||||
|
self:initializeGrid()
|
||||||
|
elseif (not self.prev_inputs.down and inputs.down) or
|
||||||
|
(not self.prev_inputs.up and inputs.up) then
|
||||||
|
self.menu_state = -self.menu_state
|
||||||
|
end
|
||||||
|
if not self.prev_inputs.rotate_left and inputs.rotate_left then
|
||||||
|
self.ready_frames = 100
|
||||||
|
self.menu_state = 0
|
||||||
|
end
|
||||||
|
self.prev_inputs = inputs
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:mainGameLoop(inputs)
|
||||||
|
self:moveCursor(inputs)
|
||||||
|
if not self.prev_inputs.rotate_left and inputs.rotate_left and
|
||||||
|
self.grid.grid[self.cursor.y+4][self.cursor.x].colour ~= "F" and
|
||||||
|
self.grid.grid[self.cursor.y+4][self.cursor.x].colour ~= "A" then
|
||||||
|
playSE("lock")
|
||||||
|
if not self:isMine(self.cursor.x, self.cursor.y) then
|
||||||
|
self:uncoverCell(self.cursor.x, self.cursor.y)
|
||||||
|
else
|
||||||
|
self.game_over = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if not self.prev_inputs.rotate_right and inputs.rotate_right then
|
||||||
|
self:flagCell(self.cursor.x, self.cursor.y)
|
||||||
|
end
|
||||||
|
self:updateFlagCount()
|
||||||
|
self.frames = self.frames + 1
|
||||||
|
self.prev_inputs = inputs
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:updateFlagCount()
|
||||||
|
local flags = math.floor(0.15 * width * height)
|
||||||
|
for y = 5, height + 4 do
|
||||||
|
for x = 1, width do
|
||||||
|
if self.grid.grid[y][x].colour == "A" then
|
||||||
|
flags = flags - 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.flags = flags
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:moveCursor(inputs)
|
||||||
|
if not self.prev_inputs.right and inputs.right then
|
||||||
|
self.cursor.x = math.min(self.cursor.x + 1, width)
|
||||||
|
elseif not self.prev_inputs.left and inputs.left then
|
||||||
|
self.cursor.x = math.max(self.cursor.x - 1, 1)
|
||||||
|
elseif not self.prev_inputs.down and inputs.down then
|
||||||
|
self.cursor.y = math.min(self.cursor.y + 1, height)
|
||||||
|
elseif not self.prev_inputs.up and inputs.up then
|
||||||
|
self.cursor.y = math.max(self.cursor.y - 1, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:flagCell(x, y)
|
||||||
|
if self.flags > 0 and self.grid.grid[y+4][x].skin == "2tie" and
|
||||||
|
self.grid.grid[y+4][x].colour ~= "F" then
|
||||||
|
self.grid.grid[y+4][x] = {
|
||||||
|
skin = "gem", colour = "A"
|
||||||
|
}
|
||||||
|
elseif self.grid.grid[y+4][x].skin == "gem" then
|
||||||
|
self.grid.grid[y+4][x] = {
|
||||||
|
skin = "2tie", colour = self.chosen_colour
|
||||||
|
}
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:uncoverCell(x, y)
|
||||||
|
if self.first_move then
|
||||||
|
self:initializeMines(x, y)
|
||||||
|
self.first_move = false
|
||||||
|
end
|
||||||
|
|
||||||
|
local stack = {
|
||||||
|
{
|
||||||
|
x = x,
|
||||||
|
y = y,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
while #stack > 0 do
|
||||||
|
local current = table.remove(stack)
|
||||||
|
local x = current.x
|
||||||
|
local y = current.y
|
||||||
|
|
||||||
|
self.grid.grid[y+4][x] = { skin = "2tie", colour = "F" }
|
||||||
|
|
||||||
|
if self:getSurroundingMineCount(x, y) == 0 then
|
||||||
|
for dy = -1, 1 do
|
||||||
|
for dx = -1, 1 do
|
||||||
|
if not (dx == 0 and dy == 0) and
|
||||||
|
x+dx >= 1 and x+dx <= width and
|
||||||
|
y+dy >= 1 and y+dy <= height and
|
||||||
|
self.grid.grid[y+4+dy][x+dx].colour ~= "F"
|
||||||
|
then
|
||||||
|
table.insert(stack, {
|
||||||
|
x = x + dx,
|
||||||
|
y = y + dy,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
for y = 5, height + 4 do
|
||||||
|
for x = 1, width do
|
||||||
|
if self.grid.grid[y][x].colour ~= "F" and
|
||||||
|
not self:isMine(x, y-4) then
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
self.completed = true
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:getSurroundingMineCount(x, y)
|
||||||
|
local mines = 0
|
||||||
|
for dy = -1, 1 do
|
||||||
|
for dx = -1, 1 do
|
||||||
|
if not (dx == 0 and dy == 0) and self:isMine(x+dx, y+dy) then
|
||||||
|
mines = mines + 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return mines
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:onGameOver()
|
||||||
|
for y = 5, height + 4 do
|
||||||
|
for x = 1, width do
|
||||||
|
if self:isMine(x, y-4) then
|
||||||
|
self.grid.grid[y][x] = { skin = "gem", colour = "R" }
|
||||||
|
else
|
||||||
|
self.grid.grid[y][x] = { skin = "2tie", colour = "F" }
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:onGameComplete()
|
||||||
|
self:onGameOver()
|
||||||
|
love.graphics.setColor(
|
||||||
|
self.game_over_frames % 4 < 2 and
|
||||||
|
{0.3, 1, 0.3, 1} or
|
||||||
|
{1, 1, 1, 1}
|
||||||
|
)
|
||||||
|
love.graphics.print("GOOD JOB!", 80 + 16 * width, 280)
|
||||||
|
end
|
||||||
|
|
||||||
|
local function opacityFunction(game, block, x, y, age)
|
||||||
|
if block.colour == "F" then
|
||||||
|
return 0.5, 0.5, 0.5, 1, 1
|
||||||
|
else
|
||||||
|
return 1, 1, 1, 1, 1
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:drawGrid()
|
||||||
|
self.grid:drawCustom(opacityFunction, self)
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.setFont(font_3x5_2)
|
||||||
|
love.graphics.setLineWidth(2)
|
||||||
|
for y = 5, height + 4 do
|
||||||
|
for x = 1, width do
|
||||||
|
if self.cursor.x == x and self.cursor.y + 4 == y then
|
||||||
|
love.graphics.rectangle("line", 48+x*16, y*16, 16, 16)
|
||||||
|
end
|
||||||
|
if self:getSurroundingMineCount(x, y-4) ~= 0 and
|
||||||
|
self.grid.grid[y][x].colour == "F" then
|
||||||
|
love.graphics.print(self:getSurroundingMineCount(x, y-4), 50+x*16, -2+y*16)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:drawScoringInfo()
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
|
||||||
|
local x = 80 + 16 * width
|
||||||
|
love.graphics.setFont(font_3x5_2)
|
||||||
|
love.graphics.print("DIMENSIONS", x, 100)
|
||||||
|
love.graphics.print("FLAGS", x, 160)
|
||||||
|
love.graphics.print("TIME ELAPSED", x, 220)
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.print(width .. " x " .. height, x, 120)
|
||||||
|
love.graphics.print(self.flags, x, 180)
|
||||||
|
love.graphics.print(formatTime(self.frames), x, 240)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Minesweeper:drawCustom()
|
||||||
|
if self.menu_state ~= 0 then
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.setColor(
|
||||||
|
self.menu_state == 1 and
|
||||||
|
{1, 1, 0.3, 1} or
|
||||||
|
{1, 1, 1, 1}
|
||||||
|
)
|
||||||
|
love.graphics.print("WIDTH: " .. width, 67, 100)
|
||||||
|
love.graphics.setColor(
|
||||||
|
self.menu_state == -1 and
|
||||||
|
{1, 1, 0.3, 1} or
|
||||||
|
{1, 1, 1, 1}
|
||||||
|
)
|
||||||
|
love.graphics.print("HEIGHT: " .. height, 67, 140)
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return Minesweeper
|
|
@ -0,0 +1,138 @@
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local Grid = require 'tetris.components.grid'
|
||||||
|
|
||||||
|
local Snake = GameMode:extend()
|
||||||
|
|
||||||
|
Snake.name = "Snake"
|
||||||
|
Snake.hash = "Snake"
|
||||||
|
Snake.tagline = "...It's literally just snake."
|
||||||
|
|
||||||
|
local moves = {
|
||||||
|
["right"] = {x=1, y=0},
|
||||||
|
["left"] = {x=-1, y=0},
|
||||||
|
["up"] = {x=0, y=-1},
|
||||||
|
["down"] = {x=0, y=1},
|
||||||
|
}
|
||||||
|
|
||||||
|
function Snake:new()
|
||||||
|
self.super:new()
|
||||||
|
self.grid = Grid(25, 24)
|
||||||
|
self.next_queue_length = 0
|
||||||
|
self.ready_frames = 1
|
||||||
|
self.ticks = 60
|
||||||
|
self.direction = "right"
|
||||||
|
self.last_move = "right"
|
||||||
|
self.snake = {
|
||||||
|
{x=11, y=15},
|
||||||
|
{x=12, y=15},
|
||||||
|
{x=13, y=15},
|
||||||
|
{x=14, y=15},
|
||||||
|
}
|
||||||
|
self.gem = {x=1, y=5}
|
||||||
|
self:generateGem()
|
||||||
|
self:updateGrid()
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:isInSnake(p)
|
||||||
|
for _, point in pairs(self.snake) do
|
||||||
|
if point.x == p.x and point.y == p.y then
|
||||||
|
return true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:updateGrid()
|
||||||
|
local snake = { skin = "2tie", colour = "G" }
|
||||||
|
local gem = { skin = "gem", colour = "R" }
|
||||||
|
self.grid:clear()
|
||||||
|
self.grid.grid[self.gem.y][self.gem.x] = gem
|
||||||
|
for y = 5, 24 do
|
||||||
|
for x = 1, 25 do
|
||||||
|
if self:isInSnake({x=x, y=y}) then
|
||||||
|
self.grid.grid[y][x] = snake
|
||||||
|
end
|
||||||
|
self.grid.grid_age[y][x] = 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:generateGem()
|
||||||
|
repeat
|
||||||
|
self.gem.x = math.random(1, 25)
|
||||||
|
self.gem.y = math.random(5, 24)
|
||||||
|
until not self:isInSnake({x=self.gem.x, y=self.gem.y})
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:advanceOneFrame(inputs, ruleset)
|
||||||
|
if self.game_over or self.completed then return true end
|
||||||
|
if self.last_move ~= "left" and not self.prev_inputs.right and inputs.right then
|
||||||
|
self.direction = "right"
|
||||||
|
elseif self.last_move ~= "right" and not self.prev_inputs.left and inputs.left then
|
||||||
|
self.direction = "left"
|
||||||
|
elseif self.last_move ~= "down" and not self.prev_inputs.up and inputs.up then
|
||||||
|
self.direction = "up"
|
||||||
|
elseif self.last_move ~= "up" and not self.prev_inputs.down and inputs.down then
|
||||||
|
self.direction = "down"
|
||||||
|
end
|
||||||
|
self.ticks = self.ticks - 1
|
||||||
|
if self.ticks <= 0 then
|
||||||
|
local move = moves[self.direction]
|
||||||
|
local new_x = self.snake[#self.snake].x + move.x
|
||||||
|
local new_y = self.snake[#self.snake].y + move.y
|
||||||
|
if (
|
||||||
|
new_x < 1 or new_x > 25 or new_y < 5 or new_y > 24 or
|
||||||
|
self:isInSnake({x=new_x, y=new_y})
|
||||||
|
) then
|
||||||
|
self.game_over = true
|
||||||
|
else
|
||||||
|
table.insert(self.snake, {
|
||||||
|
x = new_x,
|
||||||
|
y = new_y,
|
||||||
|
})
|
||||||
|
if new_x == self.gem.x and new_y == self.gem.y then
|
||||||
|
if #self.snake >= 500 then
|
||||||
|
self.completed = true
|
||||||
|
self:updateGrid()
|
||||||
|
return false
|
||||||
|
else
|
||||||
|
self:generateGem()
|
||||||
|
end
|
||||||
|
else
|
||||||
|
table.remove(self.snake, 1)
|
||||||
|
end
|
||||||
|
self:updateGrid()
|
||||||
|
self.last_move = self.direction
|
||||||
|
self.ticks = 10
|
||||||
|
end
|
||||||
|
end
|
||||||
|
self.prev_inputs = inputs
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function noOutline(game, block, x, y, age)
|
||||||
|
local x = 0.75
|
||||||
|
return x, x, x, 1, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:drawGrid()
|
||||||
|
self.grid:drawCustom(noOutline, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:drawScoringInfo()
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.setFont(font_3x5_2)
|
||||||
|
love.graphics.print("SNAKE LENGTH", 480, 130)
|
||||||
|
love.graphics.print("GEM LOCATION", 480, 210)
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.print(#self.snake, 480, 150)
|
||||||
|
love.graphics.print(self.gem.x .. ", " .. self.gem.y - 4, 480, 230)
|
||||||
|
end
|
||||||
|
|
||||||
|
function Snake:getHighscoreData()
|
||||||
|
return {
|
||||||
|
snake_length = #self.snake,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return Snake
|
|
@ -0,0 +1,143 @@
|
||||||
|
local GameMode = require 'tetris.modes.gamemode'
|
||||||
|
local Grid = require 'tetris.components.grid'
|
||||||
|
|
||||||
|
local StackerGame = GameMode:extend()
|
||||||
|
|
||||||
|
StackerGame.name = "Stacker"
|
||||||
|
StackerGame.hash = "Stacker"
|
||||||
|
StackerGame.tagline = "Hey, wait, I didn't mean this kind of block stacking!"
|
||||||
|
|
||||||
|
local block = { skin = "2tie", colour = "C" }
|
||||||
|
|
||||||
|
function StackerGame:new()
|
||||||
|
self.super:new()
|
||||||
|
self.grid = Grid(7, 19)
|
||||||
|
self.next_queue_length = 0
|
||||||
|
self.ready_frames = 1
|
||||||
|
self.row = 19
|
||||||
|
self.block_width = 3
|
||||||
|
self.position = 0
|
||||||
|
self.direction = 1
|
||||||
|
self.ticks = 0
|
||||||
|
self.are = 30
|
||||||
|
self.map = {}
|
||||||
|
block.colour = "C"
|
||||||
|
self:updateGrid()
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:getSpeed()
|
||||||
|
return 20 ^ ((self.row - 4) / 15)
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:getMaxBlockWidth()
|
||||||
|
if self.row >= 17 then return 3
|
||||||
|
elseif self.row >= 11 then return 2
|
||||||
|
else return 1 end
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:updateGrid()
|
||||||
|
local width = math.min(self:getMaxBlockWidth(), self.block_width)
|
||||||
|
self.grid:clear()
|
||||||
|
self.grid:applyMap(self.map)
|
||||||
|
for w = 0, width - 1 do
|
||||||
|
self.grid.grid[self.row][self.position - w] = block
|
||||||
|
end
|
||||||
|
for y = 5, 19 do
|
||||||
|
for x = 1, 7 do
|
||||||
|
self.grid.grid_age[y][x] = 3
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:advanceOneFrame(inputs, ruleset)
|
||||||
|
if self.game_over or self.completed then return true end
|
||||||
|
if self.are > 0 then
|
||||||
|
self.are = self.are - 1
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
if not self.prev_inputs.up and inputs.up then
|
||||||
|
self.prev_inputs = inputs
|
||||||
|
local width = math.min(self:getMaxBlockWidth(), self.block_width)
|
||||||
|
local new_width = 0
|
||||||
|
local row = {}
|
||||||
|
for w = 0, width - 1 do
|
||||||
|
if self.grid:isOccupied(self.position - w - 1, self.row) and
|
||||||
|
self.position - w >= 1 and self.position - w <= 7 then
|
||||||
|
new_width = new_width + 1
|
||||||
|
row[self.position - w] = block
|
||||||
|
end
|
||||||
|
end
|
||||||
|
if new_width == 0 then
|
||||||
|
self.game_over = true
|
||||||
|
else
|
||||||
|
playSE("lock")
|
||||||
|
self.map[self.row] = row
|
||||||
|
self.row = self.row - 1
|
||||||
|
if self.row <= 8 and self.row >= 5 then
|
||||||
|
block.colour = "R"
|
||||||
|
elseif self.row <= 4 then
|
||||||
|
block.colour = "G"
|
||||||
|
self.completed = true
|
||||||
|
self:updateGrid()
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
self.ticks = 0
|
||||||
|
self.block_width = new_width
|
||||||
|
self.position = 0
|
||||||
|
self.are = 30
|
||||||
|
self:updateGrid()
|
||||||
|
end
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
self.ticks = self.ticks + 1
|
||||||
|
if self.ticks >= self:getSpeed() then
|
||||||
|
self.ticks = self.ticks - self:getSpeed()
|
||||||
|
if self.position >= 7 + math.min(self:getMaxBlockWidth(), self.block_width) - 1 then
|
||||||
|
self.direction = -1
|
||||||
|
elseif self.position <= 1 then
|
||||||
|
self.direction = 1
|
||||||
|
end
|
||||||
|
self.position = self.position + self.direction
|
||||||
|
self:updateGrid()
|
||||||
|
end
|
||||||
|
self.prev_inputs = inputs
|
||||||
|
return false
|
||||||
|
end
|
||||||
|
|
||||||
|
local function noOutline(game, block, x, y, age)
|
||||||
|
local x = 0.75
|
||||||
|
return x, x, x, 1, 0
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:onGameComplete() end
|
||||||
|
|
||||||
|
function StackerGame:drawGrid()
|
||||||
|
self.grid:drawCustom(noOutline, self)
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:drawScoringInfo()
|
||||||
|
love.graphics.setColor(1, 1, 1, 1)
|
||||||
|
love.graphics.setFont(font_3x5_2)
|
||||||
|
love.graphics.print("<-- MAJOR PRIZE", 190, 80)
|
||||||
|
love.graphics.print("<-- MINOR PRIZE", 190, 144)
|
||||||
|
love.graphics.print("ROWS STACKED", 64, 340)
|
||||||
|
love.graphics.print("FRAMES PER MOVE", 64, 400)
|
||||||
|
love.graphics.setFont(font_3x5_3)
|
||||||
|
love.graphics.print(19 - self.row .. (self.row <= 4 and " - COMPLETE!" or ""), 64, 360)
|
||||||
|
love.graphics.print(
|
||||||
|
(
|
||||||
|
self.row > 4 and
|
||||||
|
string.format("%.02f", self:getSpeed()) or
|
||||||
|
"N/A"
|
||||||
|
),
|
||||||
|
64, 420
|
||||||
|
)
|
||||||
|
end
|
||||||
|
|
||||||
|
function StackerGame:getHighscoreData()
|
||||||
|
return {
|
||||||
|
rows = 19 - self.row,
|
||||||
|
}
|
||||||
|
end
|
||||||
|
|
||||||
|
return StackerGame
|
|
@ -0,0 +1,120 @@
|
||||||
|
local Ruleset = require 'tetris.rulesets.ruleset'
|
||||||
|
|
||||||
|
local Ascension = Ruleset:extend()
|
||||||
|
|
||||||
|
Ascension.name = "Ascension"
|
||||||
|
Ascension.hash = "Ascension"
|
||||||
|
Ascension.world = true
|
||||||
|
Ascension.colourscheme = {
|
||||||
|
I = "C",
|
||||||
|
L = "O",
|
||||||
|
J = "B",
|
||||||
|
S = "G",
|
||||||
|
Z = "R",
|
||||||
|
O = "Y",
|
||||||
|
T = "M",
|
||||||
|
}
|
||||||
|
Ascension.softdrop_lock = false
|
||||||
|
Ascension.harddrop_lock = true
|
||||||
|
|
||||||
|
Ascension.spawn_positions = {
|
||||||
|
I = { x=4, y=4 },
|
||||||
|
J = { x=4, y=5 },
|
||||||
|
L = { x=4, y=5 },
|
||||||
|
O = { x=4, y=5 },
|
||||||
|
S = { x=4, y=5 },
|
||||||
|
T = { x=4, y=5 },
|
||||||
|
Z = { x=4, y=5 },
|
||||||
|
}
|
||||||
|
|
||||||
|
Ascension.big_spawn_positions = {
|
||||||
|
I = { x=2, y=2 },
|
||||||
|
J = { x=2, y=3 },
|
||||||
|
L = { x=2, y=3 },
|
||||||
|
O = { x=2, y=3 },
|
||||||
|
S = { x=2, y=3 },
|
||||||
|
T = { x=2, y=3 },
|
||||||
|
Z = { x=2, y=3 },
|
||||||
|
}
|
||||||
|
|
||||||
|
Ascension.block_offsets = {
|
||||||
|
I={
|
||||||
|
{ {x=-1, y=0}, {x=0, y=0}, {x=1, y=0}, {x=2, y=0} },
|
||||||
|
{ {x=0, y=-1}, {x=0, y=0}, {x=0, y=1}, {x=0, y=2} },
|
||||||
|
{ {x=-2, y=0}, {x=-1, y=0}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=-2}, {x=0, y=-1}, {x=0, y=0}, {x=0, y=1} },
|
||||||
|
},
|
||||||
|
J={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=-1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1} , {x=1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=1} },
|
||||||
|
},
|
||||||
|
L={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=1, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=-1, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=-1} },
|
||||||
|
},
|
||||||
|
O={
|
||||||
|
{ {x=0, y=-1}, {x=1, y=-1}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=0, y=1}, {x=1, y=1} },
|
||||||
|
{ {x=-1, y=0}, {x=0, y=0}, {x=-1, y=1}, {x=0, y=1} },
|
||||||
|
{ {x=-1, y=-1}, {x=0, y=-1}, {x=-1, y=0}, {x=0, y=0} },
|
||||||
|
},
|
||||||
|
S={
|
||||||
|
{ {x=1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=-1, y=0} },
|
||||||
|
{ {x=1, y=1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||||
|
{ {x=-1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=-1, y=-1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=1} },
|
||||||
|
},
|
||||||
|
T={
|
||||||
|
{ {x=0, y=0}, {x=-1, y=0}, {x=1, y=0}, {x=0, y=-1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=-1}, {x=0, y=1}, {x=1, y=0} },
|
||||||
|
{ {x=0, y=0}, {x=1, y=0}, {x=-1, y=0}, {x=0, y=1} },
|
||||||
|
{ {x=0, y=0}, {x=0, y=1}, {x=0, y=-1}, {x=-1, y=0} },
|
||||||
|
},
|
||||||
|
Z={
|
||||||
|
{ {x=-1, y=-1}, {x=0, y=-1}, {x=0, y=0}, {x=1, y=0} },
|
||||||
|
{ {x=1, y=-1}, {x=1, y=0}, {x=0, y=0}, {x=0, y=1} },
|
||||||
|
{ {x=1, y=1}, {x=0, y=1}, {x=0, y=0}, {x=-1, y=0} },
|
||||||
|
{ {x=-1, y=1}, {x=-1, y=0}, {x=0, y=0}, {x=0, y=-1} },
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
-- CCW kicks, negative X for CW
|
||||||
|
Ascension.kicks = {
|
||||||
|
{x=1, y=0}, {x=0, y=1}, {x=1, y=1}, {x=0, y=2}, {x=1, y=2}, {x=2, y=0}, {x=2, y=1},
|
||||||
|
{x=2, y=2}, {x=-1, y=0}, {x=-1, y=1}, {x=0, y=-1}, {x=1, y=-1}, {x=2, y=-1}, {x=-1, y=2},
|
||||||
|
{x=-2, y=0}, {x=0, y=-2}, {x=1, y=-2}, {x=2, y=-2}, {x=-2, y=1}, {x=-2, y=2}, {x=-1, y=-1},
|
||||||
|
}
|
||||||
|
|
||||||
|
function Ascension:attemptWallkicks(piece, new_piece, rot_dir, grid)
|
||||||
|
|
||||||
|
if rot_dir == 2 then return end
|
||||||
|
|
||||||
|
local kicks = Ascension.kicks
|
||||||
|
|
||||||
|
assert(piece.rotation ~= new_piece.rotation)
|
||||||
|
|
||||||
|
for idx, o in pairs(kicks) do
|
||||||
|
offset = {
|
||||||
|
x = o.x * (rot_dir == 1 and -1 or 1),
|
||||||
|
y = o.y
|
||||||
|
}
|
||||||
|
kicked_piece = new_piece:withOffset(offset)
|
||||||
|
if grid:canPlacePiece(kicked_piece) then
|
||||||
|
self:onPieceRotate(piece, grid)
|
||||||
|
piece:setRelativeRotation(rot_dir)
|
||||||
|
piece:setOffset(offset)
|
||||||
|
return
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
end
|
||||||
|
|
||||||
|
function Ascension:onPieceDrop(piece) piece.lock_delay = 0 end
|
||||||
|
function Ascension:onPieceMove(piece) piece.lock_delay = 0 end
|
||||||
|
function Ascension:onPieceRotate(piece) piece.lock_delay = 0 end
|
||||||
|
|
||||||
|
return Ascension
|
Loading…
Reference in New Issue