78
109
self.acceleration.y = 800
80
111
if self.onWall then
81
112
self.acceleration.y = 0
114
if self.onWall == 'right' then
115
self:play('climbRight')
116
elseif self.onWall == 'left' then
117
self:play('climbLeft')
83
120
if the.keys:pressed('up') then
84
121
self.velocity.y = -200
86
122
elseif the.keys:pressed('down') then
87
123
self.velocity.y = 200
90
125
self.velocity.y = 0
126
self:freeze(self.sequences[self.currentName].frames[1])
95
130
if the.keys:pressed('left') then
96
131
self.velocity.x = -200
97
132
if self.onGround then self:play('walk') end
98
if self.onWall == 'right' then self.onWall = false end
99
if self.onWall == 'right' then self.onWall = false end
133
if self.onWall == 'right' then
135
self.leftWallAt = love.timer.getTime()
100
137
elseif the.keys:pressed('right') then
101
138
self.velocity.x = 200
102
139
if self.onGround then self:play('walk') end
103
if self.onWall == 'left' then self.onWall = false end
140
if self.onWall == 'left' then
142
self.leftWallAt = love.timer.getTime()
105
if self.onGround then self:play('stand') end
145
if not self.onWall then
146
if self.onGround then self:play('stand') end
108
if the.keys:justPressed('up') and self.onGround then
151
if the.keys:justPressed('up') and
152
(self.onGround or the.console.visible or
153
(love.timer.getTime() - self.leftWallAt < .1) ) then
109
154
self.velocity.y = -400
110
155
self.jumping = true
114
159
-- NOTE: this is an override, not a callback
116
161
self:doPhysics('x', elapsed)
162
self:collide(the.view.map)
164
-- handle X collisions
166
for _, col in ipairs(self.collisions) do
167
col.other:displaceDir(self, 'x')
168
if self.velocity.x > 0 then
169
self.onWall = 'right'
170
elseif self.velocity.x < 0 then
118
177
self.onGround = false -- right before Y collision callbacks
119
178
self:doPhysics('y', elapsed)
121
179
self:collide(the.view.map)
181
-- handle Y collisions
182
for _, col in ipairs(self.collisions) do
183
if self.velocity.y > 0 then
187
col.other:displaceDir(self, 'y')
123
192
Animation.update(self, elapsed)
194
collide = function (self, ...)
196
Animation.collide(self, ...)
197
-- I could return a true/false value here if I wanted to...
125
199
onCollide = function (self, other, xOverlap, yOverlap)
126
-- seriously, why does this even fire?
127
200
if other == the.view.map then return end
129
--print(string.format('col s{x=%i y=%i w=%i h=%i} %s', self.x, self.y, self.width, self.height, tostring(other)))
130
--print('vel.x:'..self.velocity.x.." vel.y:"..self.velocity.y)
132
-- assumption: any other collision is with a solid map tile
133
if yOverlap > xOverlap then
136
if self.velocity.x > 0 then
137
self.onWall = 'right'
138
elseif self.velocity.x < 0 then
143
elseif xOverlap > yOverlap then
144
-- check if we've moved since collisions were generated
145
local xov, yov = self:overlap(other.x, other.y,
146
other.width, other.height)
147
if xov ~= 0 and yov ~= 0 then
148
--print('y collision')
149
if self.velocity.y > 0 then
202
table.insert(self.collisions, {other = other,
204
yOverlap = yOverlap })
208
-- displace on a specific axis (monkey patch Sprite)
209
function Sprite:displaceDir(other, dir)
210
if not self.solid or self == other or not other.solid then return end
211
if STRICT then assert(other:instanceOf(Sprite), 'asked to displace a non-sprite') end
213
if other.sprites then
216
for _, spr in pairs(other.sprites) do
217
self:displace(spr, dir)
221
local dim = util.dim(dir)
223
local negMove = (other[dir] - self[dir]) + other[dim]
224
local posMove = (self[dir] + self[dim]) - other[dir]
226
-- TODO: re-add hinting?
227
if negMove < posMove then
234
other[dir] = other[dir] + chg
237
-- don't use zoetrope physics
238
function Sprite:update (elapsed)
239
if self.onUpdate then self:onUpdate(elapsed) end
164
242
GameView = View:extend {
165
243
onNew = function (self)
166
244
self:loadLayers('data/map.lua')
167
245
self.focus = the.player
168
246
self:clampTo(self.map)
248
the.recorder = Recorder:new{mousePosInterval = 9999}
249
the.app.meta:add(the.recorder)
251
the.recorder:startRecording()
253
local storage = Storage:new{filename = 'record.lua'}
255
--print(inspect(storage.data))
256
the.recorder.record = storage.data
257
the.recorder:startPlaying()
170
260
onUpdate = function (self)
261
--print('drawTook: ', the.drawTook)
172
263
--the.player:collide(self.map)
173
264
--self.map:collide(the.player)
266
-- draw = function (self, x, y)
267
-- View.draw(self, x, y)
269
-- love.graphics.print('FPS:' .. love.timer.getFPS(), 20, 20)
177
273
the.app = App:new {
178
274
onRun = function (self)
179
275
self.view = GameView:new()
180
--print(inspect(_(the.app):keys()))
181
276
self.console:watch('onGround', 'the.player.onGround')
182
277
self.console:watch('onWall', 'the.player.onWall')
278
self.console:watch('updateTook', 'the.updateTook')
279
self.console:watch('drawTook', 'the.drawTook')
280
self.console:watch('recorder state', 'the.recorder.state')
282
--the.profiler = newProfiler('time', 2000)
283
--the.profiler = newProfiler()
284
--the.profiler:start()
184
286
onUpdate = function (self, dt)
185
if the.keys:justPressed('escape') and
186
not self.console.visible then
287
if the.keys:justPressed('escape') then
290
local outfile = io.open( "profile.txt", "w+" )
291
the.profiler:report( outfile )
296
if not love.filesystem.remove('record.lua') then
297
error('could not remove record.lua')
299
local storage = Storage:new{
300
data = the.recorder.record,
301
filename = 'record.lua'
304
--print(inspect(the.recorder.record))
b'\\ No newline at end of file'
310
update = function (self, dt)
311
the.updateStart = love.timer.getMicroTime()
313
if the.updateStart then
314
the.updateTook = love.timer.getMicroTime() - the.updateStart