-
Notifications
You must be signed in to change notification settings - Fork 0
/
main.lua
282 lines (259 loc) · 7.29 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
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
--main.lua
require "src/player"
require "src/enemy"
require "src/healthgenerator"
require "src/camera"
require "src/map"
require "src/menu"
require "src/sound"
require "src/ui"
require "src/util"
local gfx = love.graphics
local fs = love.filesystem
local kb = love.keyboard
local state = 0
local paused = false
local bg
MapW = 64
MapH = 64
local player
local cam
local level
local enemies = {}
local screenScale = 1
GameData = {}
BestGame = {}
-- Loads necessary visual elements for map and UI
function love.load()
InitGameData()
local f = fs.newFile("best.snth")
f:open("w")
f:write("poopy!")
f:close()
gfx.setDefaultFilter("nearest")
LoadTileset("res/tiles/tilemap-grassy.png")
LoadTileset("res/tiles/tilemap-desert.png")
LoadTileset("res/tiles/tilemap-volcano.png")
LoadSound()
LoadMenu()
LoadUI()
bg = gfx.newImage("res/bg.png")
love.mouse.setCursor(love.mouse.newCursor("res/UI/cursor.png"))
Canvas = gfx.newCanvas()
end
-- Initializes or resets GameData
function InitGameData()
GameData.level = 0
GameData.time = 0
GameData.fireKills = 0
GameData.waterKills = 0
GameData.elecKills = 0
GameData.earthKills = 0
GameData.fireFusions = 0
GameData.waterFusions = 0
GameData.elecFusions = 0
GameData.earthFusions = 0
GameData.diff = 1
GameData.spawnTime = 10
GameData.spawnTimer = 0
end
-- (Re)Generates the map, resets and spawns the player in a new spot
function NewGame()
state = 2
InitGameData()
GenerateRoute()
NextLevel()
end
function NextLevel()
if state ~= 2 then state = 2 end
for k in pairs(enemies) do
enemies[k] = nil
end
if player ~= nil then
player:reset()
end
GameData.level = GameData.level + 1
level = GetLevel(GameData.level)
MapW = level.w
MapH = level.h
local spawn_x, spawn_y
repeat
spawn_x = math.random(1, MapW - 1)
spawn_y = math.random(1, MapH - 1)
until (GetMapTile(GameData.level, spawn_x, spawn_y) > 2)
if player == nil then
player = Player()
end
player:translate(spawn_x * 32 + 16, spawn_y * 32 + 16)
cam = Camera(player)
if GameData.level ~= 12 then
local initAmount = MapW / 2
for i = 1, initAmount do
SpawnEnemy()
end
end
state = 1
end
-- Spawns an enemy at a random spot, and decides its aspect based on the biome
function SpawnEnemy()
local spawn_x, spawn_y
local tile
repeat
spawn_x = math.random(1, MapW - 1)
spawn_y = math.random(1, MapH - 1)
tile = GetMapTile(GameData.level, spawn_x, spawn_y)
until (tile > 2 and Distance(player.x, player.y, spawn_x * 32 + 16, spawn_y * 32 + 16) > 340 - GameData.diff * 20)
local asp = GetRandomAspect(GameData.level, tile, spawn_x, spawn_y)
local blocked = false
for i = 1, #level.generators do
local h = level.generators[i]
if h.aspect == asp then
if Distance(spawn_x * 32 + 16, spawn_y * 32 + 16, h.x, h.y) > 512 then
blocked = true
break
end
end
end
if not blocked then
local enemy = Enemy(player, asp)
enemy:translate(spawn_x * 32 + 16, spawn_y * 32 + 16)
table.insert(enemies, enemy)
end
end
function love.mousepressed(x, y, button, istouch)
if state == 0 then
if button == 1 then
if ClickedPlay(x, y) then
SFX_PlayConfirm()
NewGame()
end
if ClickedTut(x, y) then
SFX_PlayConfirm()
end
if ClickedBack(x, y) then
SFX_PlayConfirm()
end
end
else
if paused then
if ClickedTut(x, y) then
SFX_PlayConfirm()
end
if ClickedBack(x, y) then
SFX_PlayConfirm()
end
end
end
end
function love.keypressed(key)
for i = 1, #level.generators do
if level.generators[i].showUI then
if key == "1" then
level.generators[i]:interact(player, 1)
elseif key == "2" then
level.generators[i]:interact(player, 2)
elseif key == "3" then
level.generators[i]:interact(player, 3)
elseif key == "4" then
level.generators[i]:interact(player, 4)
end
end
end
if key == "space" then
player:onSpace()
cam:shake(0.5, 15)
end
if key == "r" and player.dead then
NewGame()
end
if key == "escape" and state == 1 then
paused = not paused
SFX_PlayConfirm()
end
--DEBUG
if key == "p" and state == 1 then
NextLevel()
end
end
function HandleEnemySpawns(dt)
if GameData.spawnTimer > GameData.spawnTime/2 then
SpawnEnemy()
GameData.spawnTimer = 0
else
GameData.spawnTimer = GameData.spawnTimer + dt
end
end
function ScreenToWorld(sx,sy)
return sx-(-cam.x + cam.screenWidth / 2), sy-(-cam.y + cam.screenHeight / 2)
end
function love.update(dt)
if state == 1 then
if not paused then
cam:update(dt)
player:update(dt)
for i, v in pairs(enemies) do
if v ~= nil then
v:update(GameData, player, dt)
if v.state == 2 then
v = nil
end
else
table.remove(enemies, i)
end
end
for i = 1, #level.deathtiles do
if level.deathtiles[i]:checkOverlap(player) then
if player.canWalk then
player:die()
end
end
end
for i = 1, #level.generators do
level.generators[i]:checkCollision(player)
level.generators[i]:update(player, dt)
end
if not player.dead then
GameData.time = GameData.time + dt
local minutes = math.fmod(GameData.time, 3600) / 60.0
GameData.diff = 1 + minutes * 0.5
GameData.spawnTime = math.max(0.25, -math.sqrt(48 * minutes / GameData.diff) + 9)
HandleEnemySpawns(dt)
Music_PlaySynthesium()
end
if player.dead then
Music_StopSynthesium()
end
end
end
end
function love.draw()
gfx.setCanvas(Canvas)
gfx.draw(bg, 0, 0)
DrawMenu(state, paused)
if state == 1 then
if not paused then
local gscale = 1
gfx.push()
gfx.scale(gscale)
cam:draw(gscale)
DrawLevel(GameData.level, cam.x, cam.y)
local showGenUI = false
for i = 1, #level.generators do
level.generators[i]:draw(cam.x, cam.y)
if level.generators[i].showUI == true then
showGenUI = true
end
end
player:draw()
for i = 1, #enemies do
enemies[i]:draw(cam.x, cam.y)
end
gfx.pop()
DrawUI(GameData, player, showGenUI)
end
elseif state == 2 then
gfx.print("Loading...", 16,16)
end
gfx.setCanvas()
gfx.draw(Canvas, 0, 0, 0, screenScale)
end