13
13
stand = { frames = { 1 }, fps = 1 },
14
14
walk = { frames = { 2, 3 }, fps = 5 },
15
jump = { frames = { 4 }, fps = 1 }
15
jump = { frames = { 4 }, fps = 1 },
16
climbLeft = { frames = { 5, 6 }, fps = 5 },
17
climbRight = { frames = { 7, 8 }, fps = 5 }
17
21
onNew = function (self)
18
22
self.velocity.y = 0
19
23
self.maxVelocity.y = 400
33
37
assert(drag, 'active sprite has no drag property')
34
38
assert(minVel, 'active sprite has no minVelocity property')
35
39
assert(maxVel, 'active sprite has no maxVelocity property')
36
assert(_.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
40
assert(__.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
70
74
if self.falling then self.jumping = false end
71
75
--print(self.jumping, self.falling)
73
if not self.onGround then
77
if (not self.onGround) and (not self.onWall) then
78
81
self.acceleration.y = 800
84
self.acceleration.y = 0
86
if self.onWall == 'right' then
87
self:play('climbRight')
88
elseif self.onWall == 'left' then
89
self:play('climbLeft')
92
if the.keys:pressed('up') then
93
self.velocity.y = -200
94
elseif the.keys:pressed('down') then
98
self:freeze(self.sequences[self.currentName].frames[1])
80
102
if the.keys:pressed('left') then
81
103
self.velocity.x = -200
82
104
if self.onGround then self:play('walk') end
105
if self.onWall == 'right' then self.onWall = false end
83
106
elseif the.keys:pressed('right') then
84
107
self.velocity.x = 200
85
108
if self.onGround then self:play('walk') end
109
if self.onWall == 'left' then self.onWall = false end
87
if self.onGround then self:play('stand') end
111
if not self.onWall then
112
if self.onGround then self:play('stand') end
90
117
if the.keys:justPressed('up') and self.onGround then
96
123
-- NOTE: this is an override, not a callback
98
125
self:doPhysics('x', elapsed)
126
self:collide(the.view.map)
128
-- handle X collisions
130
for _, col in ipairs(self.collisions) do
131
col.other:displaceDir(self, 'x')
132
if self.velocity.x > 0 then
133
self.onWall = 'right'
134
elseif self.velocity.x < 0 then
100
141
self.onGround = false -- right before Y collision callbacks
101
142
self:doPhysics('y', elapsed)
103
143
self:collide(the.view.map)
145
-- handle Y collisions
146
for _, col in ipairs(self.collisions) do
147
if self.velocity.y > 0 then
151
col.other:displaceDir(self, 'y')
156
Animation.update(self, elapsed)
158
collide = function (self, ...)
160
Animation.collide(self, ...)
161
-- I could return a true/false value here if I wanted to...
105
163
onCollide = function (self, other, xOverlap, yOverlap)
106
-- seriously, why does this even fire?
107
164
if other == the.view.map then return end
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
166
table.insert(self.collisions, {other = other,
168
yOverlap = yOverlap })
172
-- displace on a specific axis (monkey patch Sprite)
173
function Sprite:displaceDir(other, dir)
174
if not self.solid or self == other or not other.solid then return end
175
if STRICT then assert(other:instanceOf(Sprite), 'asked to displace a non-sprite') end
177
if other.sprites then
180
for _, spr in pairs(other.sprites) do
181
self:displace(spr, dir)
188
elseif dir == 'y' then
194
local negMove = (other[dir] - self[dir]) + other[dim]
195
local posMove = (self[dir] + self[dim]) - other[dir]
197
-- TODO: re-add hinting?
198
if negMove < posMove then
205
other[dir] = other[dir] + chg
144
208
GameView = View:extend {
145
209
onNew = function (self)
146
210
self:loadLayers('data/map.lua')