74 lines
1.7 KiB
Lua
74 lines
1.7 KiB
Lua
Bitmap.render = function(self)
|
|
for y = 1, self.height do
|
|
print(table.concat(self.pixels[y], " "))
|
|
end
|
|
end
|
|
|
|
-- globals (tweak here as desired)
|
|
math.randomseed(os.time())
|
|
local W, H, MIDX = 15, 40, 7
|
|
local bitmap = Bitmap(W, H)
|
|
local AIR, PIN, BALL, FLOOR = ".", "▲", "☻", "■"
|
|
local nballs, balls = 60, {}
|
|
local frame, showEveryFrame = 1, false
|
|
|
|
-- the game board:
|
|
bitmap:clear(AIR)
|
|
for row = 1, 7 do
|
|
for col = 0, row-1 do
|
|
bitmap:set(MIDX-row+col*2+1, 1+row*2, PIN)
|
|
end
|
|
end
|
|
for col = 0, W-1 do
|
|
bitmap:set(col, H-1, FLOOR)
|
|
end
|
|
|
|
-- ball class
|
|
Ball = {
|
|
new = function(self, x, y, bitmap)
|
|
local instance = setmetatable({ x=x, y=y, bitmap=bitmap, alive=true }, self)
|
|
return instance
|
|
end,
|
|
update = function(self)
|
|
if not self.alive then return end
|
|
self.bitmap:set(self.x, self.y, AIR)
|
|
local newx, newy = self.x, self.y+1
|
|
local below = self.bitmap:get(newx, newy)
|
|
if below==PIN then
|
|
newx = newx + (math.random(2)-1)*2-1
|
|
end
|
|
local there = self.bitmap:get(newx, newy)
|
|
if there==AIR then
|
|
self.x, self.y = newx, newy
|
|
else
|
|
self.alive = false
|
|
end
|
|
self.bitmap:set(self.x, self.y, BALL)
|
|
end,
|
|
}
|
|
Ball.__index = Ball
|
|
setmetatable(Ball, { __call = function (t, ...) return t:new(...) end })
|
|
|
|
-- simulation:
|
|
local function spawn()
|
|
if nballs > 0 then
|
|
balls[#balls+1] = Ball(MIDX, 0, bitmap)
|
|
nballs = nballs - 1
|
|
end
|
|
end
|
|
|
|
spawn()
|
|
while #balls > 0 do
|
|
if frame%2==0 then spawn() end
|
|
alive = {}
|
|
for _,ball in ipairs(balls) do
|
|
ball:update()
|
|
if ball.alive then alive[#alive+1]=ball end
|
|
end
|
|
balls = alive
|
|
if frame%50==0 or #alive==0 or showEveryFrame then
|
|
print("FRAME "..frame..":")
|
|
bitmap:render()
|
|
end
|
|
frame = frame + 1
|
|
end
|