243 lines
4.2 KiB
Lua
243 lines
4.2 KiB
Lua
--*************************************************************************************************
|
||
|
||
CARDW = 200
|
||
CARDH = 300
|
||
|
||
Heart = 1
|
||
Spade = 2
|
||
Diamond = 3
|
||
Club = 4
|
||
|
||
FaceUp = true
|
||
FaceDown = false
|
||
|
||
backId = 54
|
||
|
||
TABLEAU_MARGIN_FACEUP = 80
|
||
TABLEAU_MARGIN_FACEDOWN = 10
|
||
|
||
--*************************************************************************************************
|
||
|
||
local lgni = love.graphics.newImage
|
||
local lgnq = love.graphics.newQuad
|
||
local lsgsc = love.graphics.setColor
|
||
local lgd = love.graphics.draw
|
||
local lgsc = love.graphics.setColor
|
||
local lgr = love.graphics.rectangle
|
||
|
||
--*************************************************************************************************
|
||
|
||
local cardAtlas = lgni("deck52english.png")
|
||
local cardAtlasW = cardAtlas:getWidth()
|
||
local cardAtlasH = cardAtlas:getHeight()
|
||
|
||
local cardQuads = {}
|
||
|
||
for i = 1, 57 do
|
||
cardQuads[i] = lgnq(((i-1) % 13) * CARDW, math.floor((i-1) / 13) * CARDH, CARDW, CARDH, cardAtlasW, cardAtlasH)
|
||
end
|
||
|
||
--*************************************************************************************************
|
||
|
||
local Card = { id = 1, x = 0, y = 0, w = CARDW, h = CARDH }
|
||
|
||
function Card:show()
|
||
self.showing = FaceUp
|
||
end
|
||
|
||
function Card:move(x, y)
|
||
self.x = x
|
||
self.y = y
|
||
end
|
||
|
||
function Card:hitTest(x, y)
|
||
return not (
|
||
(x < self.x) or (x > (self.x + self.w))
|
||
or (y < self.y) or (y > (self.y + self.h))
|
||
)
|
||
end
|
||
|
||
function Card:draw()
|
||
lgsc(1, 1, 1, 1)
|
||
if (self.showing == FaceUp) then
|
||
lgd(cardAtlas, cardQuads[self.id], self.x, self.y)
|
||
else
|
||
lgd(cardAtlas, cardQuads[backId], self.x, self.y)
|
||
end
|
||
|
||
lgsc(0.25, 0.25, 0.25, 1)
|
||
lgr("line", self.x, self.y, CARDW, CARDH, 4)
|
||
end
|
||
|
||
function Card:new(id, x, y, showing)
|
||
local o = {}
|
||
for k, v in pairs(self) do
|
||
o[k] = v
|
||
end
|
||
|
||
o.id = id
|
||
o.rank = math.floor(((id - 1) % 13) + 1);
|
||
o.suit = math.floor(((id - 1) / 13) + 1);
|
||
o.showing = showing
|
||
|
||
return o
|
||
end
|
||
|
||
--*************************************************************************************************
|
||
|
||
local Deck = { x = 0, y = 0 }
|
||
|
||
function Deck:empty()
|
||
local j = #self
|
||
for i = 1, j do
|
||
self[i] = nil
|
||
end
|
||
end
|
||
|
||
function Deck:push(card)
|
||
card.owner = self
|
||
card.x = self.x
|
||
card.y = self.y
|
||
self[#self + 1] = card
|
||
end
|
||
|
||
function Deck:layout()
|
||
if (self.tableau) then
|
||
local yoff = self.y
|
||
for _, card in ipairs(self) do
|
||
card.x = self.x
|
||
card.y = yoff
|
||
yoff = yoff + ((card.showing == FaceUp) and TABLEAU_MARGIN_FACEUP or TABLEAU_MARGIN_FACEDOWN)
|
||
end
|
||
else
|
||
for _, card in ipairs(self) do
|
||
card.x = self.x
|
||
card.y = self.y
|
||
end
|
||
|
||
end
|
||
end
|
||
|
||
--Fisher–Yates shuffle.
|
||
function Deck:shuffle()
|
||
for i = #self-1, 1, -1 do
|
||
j = math.random(0, i)
|
||
|
||
local tc = self[i+1]
|
||
self[i+1] = self[j+1]
|
||
self[j+1] = tc
|
||
end
|
||
end
|
||
|
||
function Deck:move(x, y)
|
||
self.x = x
|
||
self.y = y
|
||
|
||
for _, card in ipairs(self) do
|
||
card.x = x
|
||
card.y = y
|
||
end
|
||
|
||
self:layout()
|
||
end
|
||
|
||
function Deck:findCardUnderMouse(x, y)
|
||
if (#self == 0) then
|
||
return
|
||
end
|
||
|
||
for i = #self, 1, -1 do
|
||
local card = self[i]
|
||
if (card:hitTest(x, y)) then
|
||
return card
|
||
end
|
||
end
|
||
end
|
||
|
||
function Deck:hitTest(x, y)
|
||
return not (
|
||
(x < self.x) or (x > (self.x + self.w))
|
||
or (y < self.y) or (y > (self.y + self.h))
|
||
)
|
||
end
|
||
|
||
function Deck:indexOf(card)
|
||
if (#self == 0) then
|
||
return
|
||
end
|
||
|
||
for i = #self, 1, -1 do
|
||
if (card == self[i]) then
|
||
return #self - i
|
||
end
|
||
end
|
||
|
||
return math.huge
|
||
end
|
||
|
||
function Deck:draw()
|
||
if (#self == 0) then
|
||
lgsc(1, 1, 0, 1)
|
||
lgr("line", self.x, self.y, self.w, self.h, 15)
|
||
else
|
||
for _, card in ipairs(self) do
|
||
card:draw()
|
||
end
|
||
end
|
||
end
|
||
|
||
function Deck:topCard()
|
||
return self[#self]
|
||
end
|
||
|
||
function Deck:pop()
|
||
local o = self[#self]
|
||
self[#self] = nil
|
||
return o
|
||
end
|
||
|
||
function Deck:popAt(atCard)
|
||
if (#self == 0) then return end
|
||
|
||
local deck = Deck:new(mx, my, true);
|
||
|
||
local count = #self
|
||
for i = 1, count do
|
||
if (self[i] == atCard) then
|
||
for j = i, count do
|
||
deck:push(self[j])
|
||
self[j] = nil
|
||
end
|
||
break
|
||
end
|
||
end
|
||
|
||
return deck
|
||
end
|
||
|
||
function Deck:new(x, y, tableau, cards)
|
||
local o = {}
|
||
|
||
for k, v in pairs(self) do
|
||
o[k] = v
|
||
end
|
||
|
||
o.x = x or 0
|
||
o.y = y or 0
|
||
o.w = CARDW
|
||
o.h = CARDH
|
||
o.tableau = tableau
|
||
|
||
if (cards) then
|
||
for _, card in ipairs(cards) do
|
||
o:push(card)
|
||
end
|
||
end
|
||
|
||
return o
|
||
end
|
||
|
||
--*************************************************************************************************
|
||
|
||
return Deck, Card
|
||
|