/ld27

To get this branch, use:
bzr branch /bzr/ld27

« back to all changes in this revision

Viewing changes to sprite.lua

  • Committer: Josh C
  • Date: 2013-08-25 21:05:20 UTC
  • Revision ID: josh@9ix.org-20130825210520-2of9iq2uemncp336
overhaul collision and physics to fix an annoying collision resolution 
bug

Show diffs side-by-side

added added

removed removed

 
1
-- monkey patches for zoetrope Sprite
 
2
 
 
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
 
7
 
 
8
   if other.sprites then
 
9
      -- handle groups
 
10
 
 
11
      for _, spr in pairs(other.sprites) do
 
12
         self:displace(spr, dir)
 
13
      end
 
14
   else
 
15
      -- handle sprites
 
16
      local dim = util.dim(dir)
 
17
 
 
18
      local negMove = (other[dir] - self[dir]) + other[dim]
 
19
      local posMove = (self[dir] + self[dim]) - other[dir]
 
20
 
 
21
      -- TODO: re-add hinting?
 
22
      if negMove < posMove then
 
23
         chg = - negMove
 
24
      else
 
25
         chg = posMove
 
26
      end
 
27
   end
 
28
 
 
29
   other[dir] = other[dir] + chg
 
30
end
 
31
 
 
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)
 
37
 
 
38
   if self.onUpdate then self:onUpdate(elapsed) end
 
39
end
 
40
 
 
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
 
48
 
 
49
   -- check existence of properties
 
50
 
 
51
   if STRICT then
 
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')
 
58
   end
 
59
 
 
60
   vel.x = vel.x or 0
 
61
   vel.y = vel.y or 0
 
62
   vel.rotation = vel.rotation or 0
 
63
 
 
64
   -- physics
 
65
 
 
66
   if acc[dir] and acc[dir] ~= 0 then
 
67
      vel[dir] = vel[dir] + acc[dir] * elapsed
 
68
   else
 
69
      if drag[dir] then
 
70
         if vel[dir] > 0 then
 
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
 
76
         end
 
77
      end
 
78
   end
 
79
 
 
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
 
82
 
 
83
   -- ugly hack for falling through floor on really slow frames
 
84
   if math.abs(vel[dir] * elapsed) > 32 then
 
85
      print('skip')
 
86
      return
 
87
   end
 
88
 
 
89
   if vel[dir] ~= 0 then self[dir] = self[dir] + vel[dir] * elapsed end
 
90
 
 
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
 
96
   end
 
97
end