mirror of
https://github.com/SashLilac/cambridge.git
synced 2024-11-22 10:39:03 -06:00
Added Big Mode as a piece type. (#20)
Survival A3 and Phantom Mania 2 are now in their fully complete glory! :D Implements #13.
This commit is contained in:
parent
5131061e42
commit
5c5ffc6887
2
conf.lua
2
conf.lua
@ -1,6 +1,8 @@
|
||||
function love.conf(t)
|
||||
t.identity = "cambridge"
|
||||
|
||||
t.console = true
|
||||
|
||||
t.window.title = "Cambridge"
|
||||
t.window.width = 640
|
||||
t.window.height = 480
|
||||
|
@ -49,6 +49,12 @@ blocks = {
|
||||
}
|
||||
}
|
||||
|
||||
for name, blockset in pairs(blocks) do
|
||||
for shape, image in pairs(blockset) do
|
||||
image:setFilter("nearest")
|
||||
end
|
||||
end
|
||||
|
||||
misc_graphics = {
|
||||
frame = love.graphics.newImage("res/img/frame.png"),
|
||||
ready = love.graphics.newImage("res/img/ready.png"),
|
||||
|
@ -38,6 +38,10 @@ function Grid:isRowFull(row)
|
||||
end
|
||||
|
||||
function Grid:canPlacePiece(piece)
|
||||
if piece.big then
|
||||
return self:canPlaceBigPiece(piece)
|
||||
end
|
||||
|
||||
local offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = piece.position.x + offset.x
|
||||
@ -49,7 +53,29 @@ function Grid:canPlacePiece(piece)
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:canPlaceBigPiece(piece)
|
||||
local offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = piece.position.x + offset.x
|
||||
local y = piece.position.y + offset.y
|
||||
if x >= 5 or x < 0 or y >= 12 or y < 0 or
|
||||
self.grid[y * 2 + 1][x * 2 + 1] ~= empty or
|
||||
self.grid[y * 2 + 1][x * 2 + 2] ~= empty or
|
||||
self.grid[y * 2 + 2][x * 2 + 1] ~= empty or
|
||||
self.grid[y * 2 + 2][x * 2 + 2] ~= empty
|
||||
then
|
||||
return false
|
||||
end
|
||||
end
|
||||
return true
|
||||
end
|
||||
|
||||
function Grid:canPlacePieceInVisibleGrid(piece)
|
||||
if piece.big then
|
||||
return self:canPlaceBigPiece(piece)
|
||||
-- forget canPlaceBigPieceInVisibleGrid for now
|
||||
end
|
||||
|
||||
local offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = piece.position.x + offset.x
|
||||
@ -116,6 +142,10 @@ function Grid:copyBottomRow()
|
||||
end
|
||||
|
||||
function Grid:applyPiece(piece)
|
||||
if piece.big then
|
||||
self:applyBigPiece(piece)
|
||||
return
|
||||
end
|
||||
offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
x = piece.position.x + offset.x
|
||||
@ -127,6 +157,22 @@ function Grid:applyPiece(piece)
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:applyBigPiece(piece)
|
||||
offsets = piece:getBlockOffsets()
|
||||
for index, offset in pairs(offsets) do
|
||||
x = piece.position.x + offset.x
|
||||
y = piece.position.y + offset.y
|
||||
for a = 1, 2 do
|
||||
for b = 1, 2 do
|
||||
self.grid[y*2+a][x*2+b] = {
|
||||
skin = piece.skin,
|
||||
colour = piece.shape
|
||||
}
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:update()
|
||||
for y = 1, 24 do
|
||||
for x = 1, 10 do
|
||||
@ -148,6 +194,7 @@ function Grid:draw()
|
||||
love.graphics.setColor(0.5, 0.5, 0.5, 1)
|
||||
love.graphics.draw(blocks[self.grid[y][x].skin][self.grid[y][x].colour], 48+x*16, y*16)
|
||||
end
|
||||
if self.grid[y][x].skin ~= "bone" then
|
||||
love.graphics.setColor(0.8, 0.8, 0.8, 1)
|
||||
love.graphics.setLineWidth(1)
|
||||
if y > 1 and self.grid[y-1][x] == empty then
|
||||
@ -166,6 +213,7 @@ function Grid:draw()
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
function Grid:drawInvisible(opacity_function, garbage_opacity_function)
|
||||
for y = 1, 24 do
|
||||
|
@ -2,7 +2,7 @@ local Object = require 'libs.classic'
|
||||
|
||||
local Piece = Object:extend()
|
||||
|
||||
function Piece:new(shape, rotation, position, block_offsets, gravity, lock_delay, skin)
|
||||
function Piece:new(shape, rotation, position, block_offsets, gravity, lock_delay, skin, big)
|
||||
self.shape = shape
|
||||
self.rotation = rotation
|
||||
self.position = position
|
||||
@ -12,6 +12,7 @@ function Piece:new(shape, rotation, position, block_offsets, gravity, lock_delay
|
||||
self.skin = skin
|
||||
self.ghost = false
|
||||
self.locked = false
|
||||
self.big = big
|
||||
end
|
||||
|
||||
-- Functions that return a new piece to test in rotation systems.
|
||||
@ -20,7 +21,7 @@ function Piece:withOffset(offset)
|
||||
return Piece(
|
||||
self.shape, self.rotation,
|
||||
{x = self.position.x + offset.x, y = self.position.y + offset.y},
|
||||
self.block_offsets, self.gravity, self.lock_delay, self.skin
|
||||
self.block_offsets, self.gravity, self.lock_delay, self.skin, self.big
|
||||
)
|
||||
end
|
||||
|
||||
@ -30,7 +31,7 @@ function Piece:withRelativeRotation(rot)
|
||||
while new_rot >= 4 do new_rot = new_rot - 4 end
|
||||
return Piece(
|
||||
self.shape, new_rot, self.position,
|
||||
self.block_offsets, self.gravity, self.lock_delay, self.skin
|
||||
self.block_offsets, self.gravity, self.lock_delay, self.skin, self.big
|
||||
)
|
||||
end
|
||||
|
||||
@ -145,7 +146,18 @@ function Piece:draw(opacity, brightness, grid, partial_das)
|
||||
for index, offset in pairs(offsets) do
|
||||
local x = self.position.x + offset.x
|
||||
local y = self.position.y + offset.y
|
||||
love.graphics.draw(blocks[self.skin][self.shape], 64+x*16+partial_das, 16+y*16+gravity_offset)
|
||||
if self.big then
|
||||
love.graphics.draw(
|
||||
blocks[self.skin][self.shape],
|
||||
64+x*32+partial_das*2, 16+y*32+gravity_offset*2,
|
||||
0, 2, 2
|
||||
)
|
||||
else
|
||||
love.graphics.draw(
|
||||
blocks[self.skin][self.shape],
|
||||
64+x*16+partial_das, 16+y*16+gravity_offset
|
||||
)
|
||||
end
|
||||
end
|
||||
return false
|
||||
end
|
||||
|
@ -38,6 +38,7 @@ function GameMode:new()
|
||||
self.next_queue_length = 1
|
||||
self.draw_section_times = false
|
||||
self.draw_secondary_section_times = false
|
||||
self.big_mode = false
|
||||
-- variables related to configurable parameters
|
||||
self.drop_locked = false
|
||||
self.hard_drop_locked = false
|
||||
@ -298,7 +299,7 @@ function GameMode:initializeNextPiece(inputs, ruleset, piece_data, generate_next
|
||||
inputs, piece_data, self.grid, gravity,
|
||||
self.prev_inputs, self.move,
|
||||
self:getLockDelay(), self:getDropSpeed(),
|
||||
self.lock_drop, self.lock_hard_drop
|
||||
self.lock_drop, self.lock_hard_drop, self.big_mode
|
||||
)
|
||||
if self.lock_drop then
|
||||
self.drop_locked = true
|
||||
|
@ -25,6 +25,8 @@ function PhantomMania2Game:new()
|
||||
self.combo = 1
|
||||
self.hold_age = 0
|
||||
self.queue_age = 0
|
||||
self.roll_points = 0
|
||||
|
||||
self.randomizer = History6RollsRandomizer()
|
||||
|
||||
self.lock_drop = true
|
||||
@ -135,7 +137,7 @@ function PhantomMania2Game:onPieceEnter()
|
||||
end
|
||||
|
||||
local cleared_row_levels = {1, 2, 4, 6}
|
||||
local cleared_row_points = {0.02, 0.05, 0.15, 0.6}
|
||||
local cleared_row_points = {2, 6, 15, 40}
|
||||
|
||||
function PhantomMania2Game:onLineClear(cleared_row_count)
|
||||
if not self.clear then
|
||||
@ -144,6 +146,7 @@ function PhantomMania2Game:onLineClear(cleared_row_count)
|
||||
if new_level >= 1300 or self:hitTorikan(self.level, new_level) then
|
||||
if new_level >= 1300 then
|
||||
self.level = 1300
|
||||
self.big_mode = true
|
||||
end
|
||||
self.clear = true
|
||||
self.grid:clear()
|
||||
@ -152,6 +155,12 @@ function PhantomMania2Game:onLineClear(cleared_row_count)
|
||||
self.level = math.min(new_level, 1300)
|
||||
end
|
||||
self:advanceBottomRow(-cleared_row_count)
|
||||
else
|
||||
self.roll_points = self.roll_points + cleared_row_points[cleared_row_count / 2]
|
||||
if self.roll_points >= 100 then
|
||||
self.roll_points = self.roll_points - 100
|
||||
self.grade = self.grade + 1
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
@ -225,7 +234,7 @@ PhantomMania2Game.garbageOpacityFunction = function(age)
|
||||
end
|
||||
|
||||
function PhantomMania2Game:drawGrid()
|
||||
if not (self.game_over or self.clear) then
|
||||
if not (self.game_over or (self.clear and self.level < 1300)) then
|
||||
self.grid:drawInvisible(self.rollOpacityFunction, self.garbageOpacityFunction)
|
||||
else
|
||||
self.grid:draw()
|
||||
@ -243,7 +252,7 @@ local function getLetterGrade(grade)
|
||||
end
|
||||
|
||||
function PhantomMania2Game:setNextOpacity(i)
|
||||
if self.level > 1000 then
|
||||
if self.level > 1000 and self.level < 1300 then
|
||||
local hidden_next_pieces = math.floor(self.level / 100) - 10
|
||||
if i < hidden_next_pieces then
|
||||
love.graphics.setColor(1, 1, 1, 0)
|
||||
@ -258,7 +267,7 @@ function PhantomMania2Game:setNextOpacity(i)
|
||||
end
|
||||
|
||||
function PhantomMania2Game:setHoldOpacity()
|
||||
if self.level > 1000 then
|
||||
if self.level > 1000 and self.level < 1300 then
|
||||
love.graphics.setColor(1, 1, 1, 1 - math.min(1, self.hold_age / 15))
|
||||
else
|
||||
love.graphics.setColor(1, 1, 1, 1)
|
||||
|
@ -44,13 +44,14 @@ function SurvivalA3Game:getLineARE()
|
||||
end
|
||||
|
||||
function SurvivalA3Game:getDasLimit()
|
||||
if self.level < 200 then return 9
|
||||
if self.level < 100 then return 9
|
||||
elseif self.level < 500 then return 7
|
||||
else return 5 end
|
||||
end
|
||||
|
||||
function SurvivalA3Game:getLineClearDelay()
|
||||
return self:getLineARE() - 2
|
||||
if self.level < 1300 then return self:getLineARE() - 2
|
||||
else return 6 end
|
||||
end
|
||||
|
||||
function SurvivalA3Game:getLockDelay()
|
||||
@ -60,7 +61,8 @@ function SurvivalA3Game:getLockDelay()
|
||||
elseif self.level < 600 then return 13
|
||||
elseif self.level < 1100 then return 12
|
||||
elseif self.level < 1200 then return 10
|
||||
else return 8 end
|
||||
elseif self.level < 1300 then return 8
|
||||
else return 15 end
|
||||
end
|
||||
|
||||
function SurvivalA3Game:getGravity()
|
||||
@ -133,6 +135,7 @@ function SurvivalA3Game:onLineClear(cleared_row_count)
|
||||
end
|
||||
self.clear = true
|
||||
self.grid:clear()
|
||||
self.big_mode = true
|
||||
self.roll_frames = -150
|
||||
else
|
||||
self.level = math.min(new_level, 1300)
|
||||
@ -188,10 +191,8 @@ end
|
||||
local function getLetterGrade(grade)
|
||||
if grade == 0 then
|
||||
return "1"
|
||||
elseif grade <= 9 then
|
||||
return "S" .. tostring(grade)
|
||||
else
|
||||
return "M" .. tostring(grade - 9)
|
||||
return "S" .. tostring(grade)
|
||||
end
|
||||
end
|
||||
|
||||
|
@ -16,6 +16,16 @@ ARS.spawn_positions = {
|
||||
Z = { x=4, y=5 },
|
||||
}
|
||||
|
||||
ARS.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 },
|
||||
}
|
||||
|
||||
ARS.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
|
@ -16,6 +16,16 @@ ARS.spawn_positions = {
|
||||
Z = { x=4, y=5 },
|
||||
}
|
||||
|
||||
ARS.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 },
|
||||
}
|
||||
|
||||
ARS.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
|
@ -16,6 +16,16 @@ CRS.spawn_positions = {
|
||||
Z = { x=4, y=4 },
|
||||
}
|
||||
|
||||
CRS.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=2 },
|
||||
T = { x=2, y=3 },
|
||||
Z = { x=2, y=2 },
|
||||
}
|
||||
|
||||
CRS.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
|
@ -102,12 +102,19 @@ function Ruleset:getDefaultOrientation() return 1 end
|
||||
function Ruleset:initializePiece(
|
||||
inputs, data, grid, gravity, prev_inputs,
|
||||
move, lock_delay, drop_speed,
|
||||
drop_locked, hard_drop_locked
|
||||
drop_locked, hard_drop_locked, big
|
||||
)
|
||||
local spawn_positions
|
||||
if big then
|
||||
spawn_positions = self.big_spawn_positions
|
||||
else
|
||||
spawn_positions = self.spawn_positions
|
||||
end
|
||||
local piece = Piece(data.shape, data.orientation - 1, {
|
||||
x = self.spawn_positions[data.shape].x,
|
||||
y = self.spawn_positions[data.shape].y
|
||||
}, self.block_offsets, 0, 0, data.skin)
|
||||
x = spawn_positions[data.shape].x,
|
||||
y = spawn_positions[data.shape].y
|
||||
}, self.block_offsets, 0, 0, data.skin, big)
|
||||
|
||||
self:onPieceCreate(piece)
|
||||
self:rotatePiece(inputs, piece, grid, {}, true)
|
||||
self:dropPiece(inputs, piece, grid, gravity, drop_speed, drop_locked, hard_drop_locked)
|
||||
|
@ -18,6 +18,16 @@ SRS.spawn_positions = {
|
||||
Z = { x=4, y=5 },
|
||||
}
|
||||
|
||||
SRS.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 },
|
||||
}
|
||||
|
||||
SRS.block_offsets = {
|
||||
I={
|
||||
{ {x=0, y=0}, {x=-1, y=0}, {x=-2, y=0}, {x=1, y=0} },
|
||||
|
Loading…
Reference in New Issue
Block a user