13
14
stand = { frames = { 1 }, fps = 1 },
14
15
walk = { frames = { 2, 3 }, fps = 5 },
15
jump = { frames = { 4 }, fps = 1 }
16
jump = { frames = { 4 }, fps = 1 },
17
climbLeft = { frames = { 5, 6 }, fps = 5 },
18
climbRight = { frames = { 7, 8 }, fps = 5 }
17
23
onNew = function (self)
18
24
self.velocity.y = 0
19
25
self.maxVelocity.y = 400
33
39
assert(drag, 'active sprite has no drag property')
34
40
assert(minVel, 'active sprite has no minVelocity property')
35
41
assert(maxVel, 'active sprite has no maxVelocity property')
36
assert(_.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
42
assert(__.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
70
76
if self.falling then self.jumping = false end
71
77
--print(self.jumping, self.falling)
73
if not self.onGround then
79
if (not self.onGround) and (not self.onWall) then
78
83
self.acceleration.y = 800
86
self.acceleration.y = 0
88
if self.onWall == 'right' then
89
self:play('climbRight')
90
elseif self.onWall == 'left' then
91
self:play('climbLeft')
94
if the.keys:pressed('up') then
95
self.velocity.y = -200
96
elseif the.keys:pressed('down') then
100
self:freeze(self.sequences[self.currentName].frames[1])
80
104
if the.keys:pressed('left') then
81
105
self.velocity.x = -200
82
106
if self.onGround then self:play('walk') end
107
if self.onWall == 'right' then
109
self.leftWallAt = love.timer.getTime()
83
111
elseif the.keys:pressed('right') then
84
112
self.velocity.x = 200
85
113
if self.onGround then self:play('walk') end
114
if self.onWall == 'left' then
116
self.leftWallAt = love.timer.getTime()
87
if self.onGround then self:play('stand') end
119
if not self.onWall then
120
if self.onGround then self:play('stand') end
90
if the.keys:justPressed('up') and self.onGround then
125
if the.keys:justPressed('up') and
127
(love.timer.getTime() - self.leftWallAt < .1) ) then
91
128
self.velocity.y = -400
92
129
self.jumping = true
96
133
-- NOTE: this is an override, not a callback
98
135
self:doPhysics('x', elapsed)
136
self:collide(the.view.map)
138
-- handle X collisions
140
for _, col in ipairs(self.collisions) do
141
col.other:displaceDir(self, 'x')
142
if self.velocity.x > 0 then
143
self.onWall = 'right'
144
elseif self.velocity.x < 0 then
100
151
self.onGround = false -- right before Y collision callbacks
101
152
self:doPhysics('y', elapsed)
103
153
self:collide(the.view.map)
155
-- handle Y collisions
156
for _, col in ipairs(self.collisions) do
157
if self.velocity.y > 0 then
161
col.other:displaceDir(self, 'y')
105
166
Animation.update(self, elapsed)
168
collide = function (self, ...)
170
Animation.collide(self, ...)
171
-- I could return a true/false value here if I wanted to...
107
173
onCollide = function (self, other, xOverlap, yOverlap)
108
-- seriously, why does this even fire?
109
174
if other == the.view.map then return end
111
--print(string.format('col s{x=%i y=%i w=%i h=%i} %s', self.x, self.y, self.width, self.height, tostring(other)))
112
--print('vel.x:'..self.velocity.x.." vel.y:"..self.velocity.y)
114
-- assumption: any other collision is with a solid map tile
115
if yOverlap > xOverlap then
118
if self.velocity.x > 0 then
119
self.onWall = 'right'
120
elseif self.velocity.x < 0 then
125
elseif xOverlap > yOverlap then
126
-- check if we've moved since collisions were generated
127
local xov, yov = self:overlap(other.x, other.y,
128
other.width, other.height)
129
if xov ~= 0 and yov ~= 0 then
130
--print('y collision')
131
if self.velocity.y > 0 then
176
table.insert(self.collisions, {other = other,
178
yOverlap = yOverlap })
182
-- displace on a specific axis (monkey patch Sprite)
183
function Sprite:displaceDir(other, dir)
184
if not self.solid or self == other or not other.solid then return end
185
if STRICT then assert(other:instanceOf(Sprite), 'asked to displace a non-sprite') end
187
if other.sprites then
190
for _, spr in pairs(other.sprites) do
191
self:displace(spr, dir)
198
elseif dir == 'y' then
204
local negMove = (other[dir] - self[dir]) + other[dim]
205
local posMove = (self[dir] + self[dim]) - other[dir]
207
-- TODO: re-add hinting?
208
if negMove < posMove then
215
other[dir] = other[dir] + chg
146
218
GameView = View:extend {
147
219
onNew = function (self)
148
220
self:loadLayers('data/map.lua')
159
231
the.app = App:new {
160
232
onRun = function (self)
161
233
self.view = GameView:new()
162
--print(inspect(_(the.app):keys()))
163
234
self.console:watch('onGround', 'the.player.onGround')
164
235
self.console:watch('onWall', 'the.player.onWall')
236
self.console:watch('updateTook', 'the.updateTook')
237
self.console:watch('drawTook', 'the.drawTook')
239
--the.profiler = newProfiler('time', 2000)
240
--the.profiler = newProfiler()
241
--the.profiler:start()
166
243
onUpdate = function (self, dt)
167
if the.keys:justPressed('escape') and
168
not self.console.visible then
244
if the.keys:justPressed('escape') then
247
local outfile = io.open( "profile.txt", "w+" )
248
the.profiler:report( outfile )
b'\\ No newline at end of file'
255
update = function (self, dt)
256
the.updateStart = love.timer.getMicroTime()
258
if the.updateStart then
259
the.updateTook = love.timer.getMicroTime() - the.updateStart