-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.lua
134 lines (119 loc) · 3.63 KB
/
main.lua
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
require('dump')
math.randomseed(os.time())
local Field
local Image
local function isAlive(x, y)
local _, _, _, a = Field:getPixel(x, y)
return a == 1
end
local function setDead(x, y)
local color = math.random()
local color2 = math.random()
Field:setPixel(x, y, 0, color, color2, 0.9)
end
local function setAlive(x, y) Field:setPixel(x, y, 1, 1, 1, 1) end
local function updateColor(x, y)
local r, g, b, a = Field:getPixel(x, y)
Field:setPixel(x, y, r, math.max(0, g - 0.002), math.max(0, b - 0.01), 1)
end
local function getNumNeighbors(x, y)
local w, h = Field:getDimensions()
if x < 1 or x > w - 2 or y < 1 or y > h - 2 then return 0 end
local count = 0
for i = x - 1, x + 1 do
for j = y - 1, y + 1 do
if (i ~= x or j ~= y) and isAlive(i, j) then
count = count + 1
end
end
end
return count
end
local function tickField()
local dead_bois = {}
local alive_bois = {}
local w, h = Field:getDimensions()
for i = 0, w - 1 do
for j = 0, h - 1 do
local num = getNumNeighbors(i, j)
if isAlive(i, j) then
if num ~= 2 and num ~= 3 then
table.insert(dead_bois, {i = i, j = j})
else
updateColor(i, j)
end
else
local r, g, b, a = Field:getPixel(i, j)
Field:setPixel(i, j, r, g, b, math.max(0.2, a * 0.99))
if num == 3 then
table.insert(alive_bois, {i = i, j = j})
end
end
end
end
for _, boi in pairs(dead_bois) do setDead(boi.i, boi.j) end
for _, boi in pairs(alive_bois) do setAlive(boi.i, boi.j) end
end
local function buildField()
local w, h = love.graphics.getDimensions()
Field = love.image.newImageData(w / Scale, h / Scale)
print('created with ', w / 2, h / 2)
for i = 0, (w / Scale) - 1 do
for j = 0, (h / Scale) - 1 do
local alive = math.random() > 0.7
if alive then setAlive(i, j) end
end
end
Image = love.graphics.newImage(Field)
return Field
end
function love.load()
Shader = love.graphics.newShader("glow.glsl")
love.graphics.setDefaultFilter('linear', 'nearest', 0)
-- init field
RefreshRate = 0.1
Paused = false
Fps = 0
Cooldown = 0
Debug = true
Shading = false
Scale = 2
Field = buildField()
end
function love.keypressed(key, scancode, isrepeat)
if key == "r" then
print('reset')
Field = buildField()
end
if key == "t" then tickField() end
if key == "space" then Paused = not Paused end
if key == "d" then Debug = not Debug end
if key == "s" then Shading = not Shading end
if key == "2" then Scale = 2 end
if key == "4" then Scale = 4 end
end
function love.mousepressed(x, y, button, istouch)
if button == 1 then
print('set pixel', x, y)
print('field coordinate', x / Scale, y / Scale)
setAlive(math.floor(x / Scale), math.floor(y / Scale))
end
if button == 2 then Paused = not Paused end
end
local function round(n) return math.floor(n * 1000) / 1000 end
function love.update(dt)
Fps = round(1 / dt)
Cooldown = Cooldown + dt
if (Cooldown > RefreshRate) then
if not Paused then tickField() end
Cooldown = 0
end
Image:replacePixels(Field)
end
function love.draw()
if Debug then love.graphics.print(Fps, 10, 10) end
if Shading then love.graphics.setShader(Shader) end
love.graphics.setColor(1, 1, 1);
love.graphics.draw(Image, 0, 0, 0, Scale, Scale)
love.graphics.setShader()
end