26
13
stand = { frames = { 1 }, fps = 1 },
27
14
walk = { frames = { 2, 3 }, fps = 5 },
28
jump = { frames = { 4 }, fps = 1 },
29
climbLeft = { frames = { 5, 6 }, fps = 5 },
30
climbRight = { frames = { 7, 8 }, fps = 5 }
15
jump = { frames = { 4 }, fps = 1 }
35
17
onNew = function (self)
36
18
self.velocity.y = 0
37
19
self.maxVelocity.y = 400
51
33
assert(drag, 'active sprite has no drag property')
52
34
assert(minVel, 'active sprite has no minVelocity property')
53
35
assert(maxVel, 'active sprite has no maxVelocity property')
54
assert(__.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
36
assert(_.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
78
60
if maxVel[dir] and vel[dir] > maxVel[dir] then vel[dir] = maxVel[dir] end
80
62
if vel[dir] ~= 0 then self[dir] = self[dir] + vel[dir] * elapsed end
82
if self[dir] < 0 then self[dir] = 0 end
83
local edge = the.view.map[util.dim(dir)] -
84
the.player[util.dim(dir)]
85
-- TODO: take map position into account
86
if self[dir] > edge then self[dir] = edge end
88
64
onStartFrame = function (self)
89
65
-- this is all in startframe so it happens before
94
70
if self.falling then self.jumping = false end
95
71
--print(self.jumping, self.falling)
97
if (not self.onGround) and (not self.onWall) then
73
if not self.onGround then
101
78
self.acceleration.y = 800
104
self.acceleration.y = 0
106
if self.onWall == 'right' then
107
self:play('climbRight')
108
elseif self.onWall == 'left' then
109
self:play('climbLeft')
112
if the.keys:pressed('up') then
113
self.velocity.y = -200
114
elseif the.keys:pressed('down') then
115
self.velocity.y = 200
118
self:freeze(self.sequences[self.currentName].frames[1])
122
80
if the.keys:pressed('left') then
123
81
self.velocity.x = -200
124
82
if self.onGround then self:play('walk') end
125
if self.onWall == 'right' then
127
self.leftWallAt = love.timer.getTime()
129
83
elseif the.keys:pressed('right') then
130
84
self.velocity.x = 200
131
85
if self.onGround then self:play('walk') end
132
if self.onWall == 'left' then
134
self.leftWallAt = love.timer.getTime()
137
if not self.onWall then
138
if self.onGround then self:play('stand') end
87
if self.onGround then self:play('stand') end
143
if the.keys:justPressed('up') and
144
(self.onGround or the.console.visible or
145
(love.timer.getTime() - self.leftWallAt < .1) ) then
90
if the.keys:justPressed('up') and self.onGround then
146
91
self.velocity.y = -400
147
92
self.jumping = true
151
96
-- NOTE: this is an override, not a callback
153
98
self:doPhysics('x', elapsed)
154
self:collide(the.view.map)
156
-- handle X collisions
158
for _, col in ipairs(self.collisions) do
159
col.other:displaceDir(self, 'x')
160
if self.velocity.x > 0 then
161
self.onWall = 'right'
162
elseif self.velocity.x < 0 then
169
100
self.onGround = false -- right before Y collision callbacks
170
101
self:doPhysics('y', elapsed)
171
103
self:collide(the.view.map)
173
-- handle Y collisions
174
for _, col in ipairs(self.collisions) do
175
if self.velocity.y > 0 then
179
col.other:displaceDir(self, 'y')
184
Animation.update(self, elapsed)
186
collide = function (self, ...)
188
Animation.collide(self, ...)
189
-- I could return a true/false value here if I wanted to...
191
105
onCollide = function (self, other, xOverlap, yOverlap)
106
-- seriously, why does this even fire?
192
107
if other == the.view.map then return end
194
table.insert(self.collisions, {other = other,
196
yOverlap = yOverlap })
109
--print(string.format('col s{x=%i y=%i w=%i h=%i} %s', self.x, self.y, self.width, self.height, tostring(other)))
110
--print('vel.x:'..self.velocity.x.." vel.y:"..self.velocity.y)
112
-- assumption: any other collision is with a solid map tile
113
if yOverlap > xOverlap then
116
if self.velocity.x > 0 then
117
self.onWall = 'right'
118
elseif self.velocity.x < 0 then
123
elseif xOverlap > yOverlap then
124
-- check if we've moved since collisions were generated
125
local xov, yov = self:overlap(other.x, other.y,
126
other.width, other.height)
127
if xov ~= 0 and yov ~= 0 then
128
--print('y collision')
129
if self.velocity.y > 0 then
200
function Sprite:displaceDir(other, dir)
201
if not self.solid or self == other or not other.solid then return end
202
if STRICT then assert(other:instanceOf(Sprite), 'asked to displace a non-sprite') end
204
if other.sprites then
207
for _, spr in pairs(other.sprites) do
208
self:displace(spr, dir)
212
local dim = util.dim(dir)
214
local negMove = (other[dir] - self[dir]) + other[dim]
215
local posMove = (self[dir] + self[dim]) - other[dir]
217
-- TODO: re-add hinting?
218
if negMove < posMove then
225
other[dir] = other[dir] + chg
228
144
GameView = View:extend {
229
145
onNew = function (self)
230
146
self:loadLayers('data/map.lua')
242
157
the.app = App:new {
243
158
onRun = function (self)
244
159
self.view = GameView:new()
160
--print(inspect(_(the.app):keys()))
245
161
self.console:watch('onGround', 'the.player.onGround')
246
162
self.console:watch('onWall', 'the.player.onWall')
247
self.console:watch('updateTook', 'the.updateTook')
248
self.console:watch('drawTook', 'the.drawTook')
250
--the.profiler = newProfiler('time', 2000)
251
--the.profiler = newProfiler()
252
--the.profiler:start()
254
164
onUpdate = function (self, dt)
255
if the.keys:justPressed('escape') then
258
local outfile = io.open( "profile.txt", "w+" )
259
the.profiler:report( outfile )
165
if the.keys:justPressed('escape') and
166
not self.console.visible then
266
update = function (self, dt)
267
the.updateStart = love.timer.getMicroTime()
269
if the.updateStart then
270
the.updateTook = love.timer.getMicroTime() - the.updateStart
b'\\ No newline at end of file'