33
35
assert(drag, 'active sprite has no drag property')
34
36
assert(minVel, 'active sprite has no minVelocity property')
35
37
assert(maxVel, 'active sprite has no maxVelocity property')
36
assert(_.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
38
assert(__.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
70
72
if self.falling then self.jumping = false end
71
73
--print(self.jumping, self.falling)
73
if not self.onGround then
75
if (not self.onGround) and (not self.onWall) then
78
79
self.acceleration.y = 800
82
self.acceleration.y = 0
84
if the.keys:pressed('up') then
85
self.velocity.y = -200
87
elseif the.keys:pressed('down') then
80
96
if the.keys:pressed('left') then
81
97
self.velocity.x = -200
82
98
if self.onGround then self:play('walk') end
99
if self.onWall == 'right' then self.onWall = false end
83
100
elseif the.keys:pressed('right') then
84
101
self.velocity.x = 200
85
102
if self.onGround then self:play('walk') end
103
if self.onWall == 'left' then self.onWall = false end
87
105
if self.onGround then self:play('stand') end
106
if not self.onWall then
90
111
if the.keys:justPressed('up') and self.onGround then
96
117
-- NOTE: this is an override, not a callback
98
119
self:doPhysics('x', elapsed)
120
self:collide(the.view.map)
122
-- handle X collisions
124
for _, col in ipairs(self.collisions) do
125
col.other:displaceDir(self, 'x')
126
if self.velocity.x > 0 then
127
self.onWall = 'right'
128
elseif self.velocity.x < 0 then
100
135
self.onGround = false -- right before Y collision callbacks
101
136
self:doPhysics('y', elapsed)
103
137
self:collide(the.view.map)
139
-- handle Y collisions
140
for _, col in ipairs(self.collisions) do
141
if self.velocity.y > 0 then
145
col.other:displaceDir(self, 'y')
105
150
Animation.update(self, elapsed)
152
collide = function (self, ...)
154
Animation.collide(self, ...)
155
-- I could return a true/false value here if I wanted to...
107
157
onCollide = function (self, other, xOverlap, yOverlap)
108
-- seriously, why does this even fire?
109
158
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
160
table.insert(self.collisions, {other = other,
162
yOverlap = yOverlap })
166
-- displace on a specific axis (monkey patch Sprite)
167
function Sprite:displaceDir(other, dir)
168
if not self.solid or self == other or not other.solid then return end
169
if STRICT then assert(other:instanceOf(Sprite), 'asked to displace a non-sprite') end
171
if other.sprites then
174
for _, spr in pairs(other.sprites) do
175
self:displace(spr, dir)
182
elseif dir == 'y' then
188
local negMove = (other[dir] - self[dir]) + other[dim]
189
local posMove = (self[dir] + self[dim]) - other[dir]
191
-- TODO: re-add hinting?
192
if negMove < posMove then
199
other[dir] = other[dir] + chg
146
202
GameView = View:extend {
147
203
onNew = function (self)
148
204
self:loadLayers('data/map.lua')