1
-- monkey patches for zoetrope Sprite
3
-- displace on a specific axis
4
function Sprite:displaceDir(other, dir)
5
if not self.solid or self == other or not other.solid then return end
6
if STRICT then assert(other:instanceOf(Sprite), 'asked to displace a non-sprite') end
11
for _, spr in pairs(other.sprites) do
12
self:displace(spr, dir)
16
local dim = util.dim(dir)
18
local negMove = (other[dir] - self[dir]) + other[dim]
19
local posMove = (self[dir] + self[dim]) - other[dir]
21
-- TODO: re-add hinting?
22
if negMove < posMove then
29
other[dir] = other[dir] + chg
32
-- don't use zoetrope physics
33
function Sprite:update(elapsed)
34
self:doPhysics('x', elapsed)
35
self:doPhysics('y', elapsed)
36
self:doPhysics('rotation', elapsed)
38
if self.onUpdate then self:onUpdate(elapsed) end
41
-- directional physics
42
function Sprite:doPhysics(dir, elapsed)
43
local vel = self.velocity
44
local acc = self.acceleration
45
local drag = self.drag
46
local minVel = self.minVelocity
47
local maxVel = self.maxVelocity
49
-- check existence of properties
52
assert(vel, 'active sprite has no velocity property')
53
assert(acc, 'active sprite has no acceleration property')
54
assert(drag, 'active sprite has no drag property')
55
assert(minVel, 'active sprite has no minVelocity property')
56
assert(maxVel, 'active sprite has no maxVelocity property')
57
assert(dir=='x' or dir=='y' or dir=='rotation', 'direction should be x, y, or rotation')
62
vel.rotation = vel.rotation or 0
66
if acc[dir] and acc[dir] ~= 0 then
67
vel[dir] = vel[dir] + acc[dir] * elapsed
71
vel[dir] = vel[dir] - drag[dir] * elapsed
72
if vel[dir] < 0 then vel[dir] = 0 end
73
elseif vel[dir] < 0 then
74
vel[dir] = vel[dir] + drag[dir] * elapsed
75
if vel[dir] > 0 then vel[dir] = 0 end
80
if minVel[dir] and vel[dir] < minVel[dir] then vel[dir] = minVel[dir] end
81
if maxVel[dir] and vel[dir] > maxVel[dir] then vel[dir] = maxVel[dir] end
83
-- ugly hack for falling through floor on really slow frames
84
if math.abs(vel[dir] * elapsed) > 32 then
89
if vel[dir] ~= 0 then self[dir] = self[dir] + vel[dir] * elapsed end
91
if dir == 'x' or dir == 'y' then -- doesn't make sense for rotation
92
if self[dir] < 0 then self[dir] = 0 end
93
local edge = the.activeMaze[util.dim(dir)] - the.player[util.dim(dir)]
94
-- TODO: take map position into account
95
if self[dir] > edge then self[dir] = edge end