knucklebones/classes/die.lua
2023-08-12 11:36:14 +02:00

107 lines
2.9 KiB
Lua

--- @class Die
Die = {
x = 0,
y = 0,
size = 16,
dx = math.random(0, 1) == 0 and -1 or 1,
dy = math.random(0, 1) == 0 and -1 or 1,
value = nil,
--
box = nil,
bouncing = false,
angle = 0,
scale = 1,
--
bg = nil,
--
---
---@param self Die
set_random_value = function(self)
-- Don't change the value if the die is barely moving
if (math.abs(self.dx)<0.25 or math.abs(self.dy)<0.25) then
return
end
local n
repeat
n = math.random(1, 6)
until n ~= self.value
self.value = n
end,
---
--- @param self Die
update = function(self)
-- bounce off walls
if math.abs(self.dx) < 0.05 then self.dx = 0 end
if math.abs(self.dy) < 0.05 then self.dy = 0 end
if self.box then
if self.x < self.box.x then
self.x = self.box.x
self.dx = -self.dx
self:set_random_value()
end
if self.x > self.box.x + self.box.width - self.size then
self.x = self.box.x + self.box.width - self.size
self.dx = -self.dx
self:set_random_value()
end
if self.y < self.box.y then
self.y = self.box.y
self.dy = -self.dy
self:set_random_value()
end
if self.y > self.box.y + self.box.height - self.size then
self.y = self.box.y + self.box.height - self.size
self.dy = -self.dy
self:set_random_value()
end
end
if not self.bouncing then
-- reduce speed
if self.dx ~= 0 then
self.dx = self.dx * 0.85
end
if self.dy ~= 0 then
self.dy = self.dy * 0.85
end
end
self.x = self.x + self.dx
self.y = self.y + self.dy
end,
---
---@param self Die
draw = function(self, colorkey)
colorkey = colorkey or 0
if self.bg then
swap_color(12, self.bg)
end
swap_color(8, 0)
-- aspr() uses the center as anchor point, so we offset the drawing position
-- while keeping the scaling centered
local offset = 8
aspr(die_spr[self.value], self.x + offset, self.y + offset, colorkey, self.scale, self.scale, 0, self.angle, 2, 2)
-- rectb(self.x, self.y, 16, 16, 2)
reset_colors(12, 8)
end
}
---comment
---@param o Die
---@return Die
function Die:new(o)
o = o or {} -- create object if user does not provide one
setmetatable(o, self)
self.__index = self
if o.box then
o.angle = math.random() < .5 and 180 or -180
o.x = o.box.x + math.random(0, o.box.width - o.size)
o.y = o.box.y + math.random(0, o.box.height - o.size)
end
return o
end