-
Notifications
You must be signed in to change notification settings - Fork 3
/
game.lua
252 lines (245 loc) · 9.45 KB
/
game.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
function startgame(map, noplay)
stopallsounds()
mainmenu.unload()
hud.score = false
hud.lvl1 = false
hud.lvl2 = false
--ok, let's do the stuff we'd normally do in load
--we create a world, set gravity, the collision callback, and load the map
game.world = love.physics.newWorld(1830, 1230)
game.world:setMeter(1)
game.world:setGravity(0, -9.81)
game.world:setCallbacks(game.collision)
game.map = loadmap(map, game.worlds)
--the player can't sleep, but this doesn't seem to help, weird..
game.map.Objects.player._body:setAllowSleeping(false)
center = {}
center.x = love.graphics.getWidth()/2
center.y = love.graphics.getHeight()/2
--some variables which need to be initialized
game.allowjump = true
game.activelayer = 1
game.layers = 2
game.finished = false
game.score = 0
editor.mapstarted()
getCamera():setOrigin(game.map.Objects.player._body:getX()-love.graphics.getWidth()/2, game.map.Objects.player._body:getY()-love.graphics.getHeight()/2)
if game.map.Mission and not noplay then LBP.messageBox(game.map.Mission) end
if game.map.Resources.ambiance and not noplay then LBP.play(game.map.Resources.ambiance, true) end
LBP.showScore(game.map.ShowScore)
if game.map.init then game.map.init() end
end
game = {}
function game.update(dt)
console:update()
if editor.active then
editor.context:update(dt)
local x, y = love.mouse.getPosition( )
if editor.rotatemode then
local o = game.map.Objects[editor.selectedobject]
local ox, oy = cameras.default:pos(o._body:getX(), o._body:getY())
o._body:setAngle(math.atan2(x-ox, y-oy))
else
if x < 40 then
local g = getCamera()
local ox, oy = g:getOrigin()
g:setOrigin(ox - (40-x)/40, oy)
elseif x > (camera.love.graphics.getWidth() - 40) then
local g = getCamera()
local ox, oy = g:getOrigin()
g:setOrigin(ox + (x-camera.love.graphics.getWidth()+40)/40, oy)
end
if y < 40 and x > 562 then
local g = getCamera()
local ox, oy = g:getOrigin()
g:setOrigin(ox, oy + (40-y)/40)
elseif y > (camera.love.graphics.getHeight() - 40) then
local g = getCamera()
local ox, oy = g:getOrigin()
g:setOrigin(ox, oy - (y-camera.love.graphics.getHeight()+40)/40)
end
end
love.timer.sleep(15)
return
end
--allow flying if we are debugging
if dbg then game.allowjump = true end
--FIX: setAllowSleep fails, do it manually
game.map.Objects.player._body:wakeUp()
--get the velocity, process the input, and set it, preserves untouched velocity..
local x, y = game.map.Objects.player._body:getLinearVelocity()
if activejoystick then
local joyx = love.joystick.getAxis(activejoystick, love.joystick_axis_horizontal)
if math.abs(joyx) >= 0.05 then
x = joyx * 3.5
end
if love.joystick.getAxis(activejoystick, love.joystick_axis_vertical) <= -0.5 and game.allowjump then
game.allowjump = false
y = 5
end
if love.joystick.getAxis(activejoystick, love.joystick_axis_vertical) >= 0.5 and dbg then
y = -7.5
end
end
if love.keyboard.isDown(love.key_left) then
x = -3.5
end
if love.keyboard.isDown(love.key_right) then
x = 3.5
end
if love.keyboard.isDown(love.key_up) and game.allowjump then
game.allowjump = false
y = 5
end
if love.keyboard.isDown(love.key_down) and dbg then
y = - 7.5
end
game.map.Objects.player._body:setLinearVelocity(x, y)
--players don't use their heads for walking
local angle = game.map.Objects.player._body:getAngle()
if angle > 1.35 then
game.map.Objects.player._body:setAngle(0)
elseif angle < -1.35 then
game.map.Objects.player._body:setAngle(0)
end
--finally, we told Box2D what we want, produce some results..
game.world:update(dt)
--follow the player
getCamera():setOrigin(game.map.Objects.player._body:getX()-love.graphics.getWidth()/2, game.map.Objects.player._body:getY()-love.graphics.getHeight()/2)
--check if he finished, round the position first
local x, y = game.map.Objects.player._body:getPosition()
if not game.finished and math.floor(x+0.5) == game.map.Finish.x and math.floor(y+0.5) == game.map.Finish.y and game.map.Objects.player._shapes[1]:getCategory() == game.map.Finish.position and math.abs(select(2, game.map.Objects.player._body:getLinearVelocity())) < 0.01 then
LBP.finish()
end
if x < -30 or x > 30 and y > 20 or y < -20 then
LBP.kill("player")
end
if game.map.update then game.map.update(dt) end
for i, v in ipairs(requireupdate) do v:update(dt) end
--preserve some CPU, may need some tweaking when the engine becomes heavier
love.timer.sleep(15)
end
function game.draw()
--draw the background, of course
if game.map.Resources.background.hasInternalDraw then
game.map.Resources.background.resource:draw(center.x, center.y, 0, game.map.BackgroundScale.x/150, (game.map.BackgroundScale.y or game.map.BackgroundScale.x)/150)
else
love.graphics.draw(game.map.Resources.background.resource, center.x, center.y, 0, game.map.BackgroundScale.x/150, (game.map.BackgroundScale.y or game.map.BackgroundScale.x)/150)
end
--ask the map to draw each layer, usually done using the standard functions
game.map:drawLayers()
--same goes for menu
menu.draw()
if editor.active then
local sel
if editor.selectedobject then
sel = game.map.Objects[editor.selectedobject]
love.graphics.setColor(100, 100, 255, 255)
love.graphics.setBlendMode('additive')
LBP.draw(sel)
love.graphics.setColor(255, 255, 255, 255)
love.graphics.setBlendMode('alpha')
end
setCamera(cameras.editor)
if editor.selectedobject and sel
--and editor.default_action == editor.popup_place
then
local x, y = cameras.default:pos(sel._body:getX(), sel._body:getY())
local txt = "Layers: "..table.concat(sel._positions,", ")
local f = love.graphics.getFont()
local w, h = f:getWidth(txt), f:getHeight()
love.graphics.setColor(0, 0, 0, 155)
love.graphics.rectangle(love.draw_fill, x-w/2-5, y-h-30, w+10, h+5)
love.graphics.setColor(255, 255, 255, 255)
love.graphics.print(txt, x-w/2, y-30)
end
local x, y = love.mouse.getPosition( )
if editor.cursortexture and editor.view_settings.hidden and (y > 52 or x > 460) and (editor.view_objects.hidden or (x < 370 or x > 480 or y > 42+42 * #editor.objectbuttons)) then
love.graphics.setColor(255, 255, 255, 150)
local a = editor.cursorobject._lite and 0 or -editor.cursorobject._body:getAngle()
setCamera(cameras.default)
local Px, Py = cameras.default:unpos(x, y)
if editor.cursortexture.hasInternalDraw then
editor.cursortexture.resource:draw(Px, Py, a, editor.cursorobject.TextureScale.x/150, (editor.cursorobject.TextureScale.y or editor.cursorobject.TextureScale.x)/150)
else
love.graphics.draw(editor.cursortexture.resource, Px, Py, a, editor.cursorobject.TextureScale.x/150, (editor.cursorobject.TextureScale.y or editor.cursorobject.TextureScale.x)/150)
end
setCamera(cameras.hud)
love.graphics.setColor(255, 255, 255, 255)
end
setCamera(cameras.hud)
editor.context:display()
if not editor.cursorobject then
love.graphics.setColor(0, 0, 0, 155)
local f = love.graphics.getFont()
love.graphics.rectangle(love.draw_fill, 460, 10, f:getWidth(editor.default_action.value)+10, f:getHeight()+10)
love.graphics.setColor(255, 255, 255, 255)
love.graphics.print(editor.default_action.value, 465, 26)
end
setCamera(cameras.default)
else
--draw HUD
hud.draw()
end
if download.active then
download.draw()
end
end
function game.collision(a, b, coll)
--did a player collide? if so, cue our nice lazy way of solving stuff
--let the player jump! (allow it)
if a == "player" or b == "player" then
game.allowjump = true
end
if game.map.Objects[a] and game.map.Objects[a].collision then game.map.Objects[a]:collision(b) end
if game.map.Objects[b] and game.map.Objects[b].collision then game.map.Objects[b]:collision(a) end
if game.map.collision then game.map:collision(a, b) end
end
function game.switchlayer(layer)
--we need to go to another layer, this is in a seperate function to prevent
--code duplication, though the code which calls this is pretty similar every
--time
--courtesy of Robin, comments welcome
game.activelayer = layer
local pl = game.map.Objects.player
local posses = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16}
table.remove(posses, game.activelayer) -- oh god, this is awful
for k,v in ipairs(pl._shapes) do
v:setCategory(game.activelayer)
v:setMask(unpack(posses))
end
end
function game.keypressed(key)
if menu.keypressed(key) then return end
if not editor.active or editor.context.firstResponder.cellClass~=LoveUI.TextfieldCell then
if key == love.key_z then --z is switch to next layer
game.switchlayer((game.activelayer % game.layers) + 1)
elseif key == love.key_a then --a to previous
game.switchlayer(((game.activelayer-2) % game.layers) + 1)
--now we'll check for the number keys, if one is pressed, switch to appropriate
--layer, if it exists.
elseif key > love.key_0 and key <= love.key_9 then
local l = string.byte(key) - string.byte(love.key_0)
if game.layers >= l then
game.switchlayer(l)
end
elseif key > love.key_kp0 and key <= love.key_kp9 then
local l = string.byte(key,3) - string.byte(love.key_0)
if game.layers >= l then
game.switchlayer(l)
end
elseif key == love.key_minus then
cameras.default:scaleBy(.8, .8)
elseif key == love.key_equals then
cameras.default:scaleBy(1.25, 1.25)
end
end
end
function game.joystickpressed(j, button)
if j ~= activejoystick then return end
if button == 0 then
game.switchlayer((game.activelayer % game.layers) + 1)
elseif button == 1 then
game.switchlayer(((game.activelayer-2) % game.layers) + 1)
end
end