/zoeplat

To get this branch, use:
bzr branch http://9ix.org/bzr/zoeplat

« back to all changes in this revision

Viewing changes to main.lua

  • Committer: Josh C
  • Date: 2013-03-12 17:21:28 UTC
  • Revision ID: josh@9ix.org-20130312172128-l336vwqawo81c6sm
really easy version of knowing when we reached the top of a wall.  
similar to how we're doing onGround.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
STRICT = true
2
 
DEBUG = false
 
2
DEBUG = true
3
3
 
4
4
require 'zoetrope'
5
5
__ = require 'underscore'
6
6
--inspect = require 'inspect'
7
 
require 'pepperprof'
8
 
require 'getopt_alt'
9
 
 
10
 
require 'sprite'
11
 
require 'player'
12
 
 
13
 
util = {
14
 
   dim = function(dir)
 
7
 
 
8
Player = Animation:extend {
 
9
   image = 'data/player.png',
 
10
   height = 32,
 
11
   width = 32,
 
12
   sequences = {
 
13
      stand = { frames = { 1 }, fps = 1 },
 
14
      walk = { frames = { 2, 3 }, fps = 5 },
 
15
      jump = { frames = { 4 }, fps = 1 }
 
16
   },
 
17
   collisions = {},
 
18
   onWall = false,
 
19
   onNew = function (self)
 
20
              self.velocity.y = 0
 
21
              self.maxVelocity.y = 400
 
22
           end,
 
23
   doPhysics = function (self, dir, elapsed)
 
24
                  local vel = self.velocity
 
25
                  local acc = self.acceleration
 
26
                  local drag = self.drag
 
27
                  local minVel = self.minVelocity
 
28
                  local maxVel = self.maxVelocity
 
29
 
 
30
                  -- check existence of properties
 
31
 
 
32
                  if STRICT then
 
33
                     assert(vel, 'active sprite has no velocity property')
 
34
                     assert(acc, 'active sprite has no acceleration property')
 
35
                     assert(drag, 'active sprite has no drag property')
 
36
                     assert(minVel, 'active sprite has no minVelocity property')
 
37
                     assert(maxVel, 'active sprite has no maxVelocity property')
 
38
                     assert(__.include({'x','y','rotation'}, dir), 'direction should be x, y, or rotation')
 
39
                  end
 
40
 
 
41
                  vel.x = vel.x or 0
 
42
                  vel.y = vel.y or 0
 
43
                  vel.rotation = vel.rotation or 0
 
44
 
 
45
                  -- physics
 
46
 
 
47
                  if acc[dir] and acc[dir] ~= 0 then
 
48
                     vel[dir] = vel[dir] + acc[dir] * elapsed
 
49
                  else
 
50
                     if drag[dir] then
 
51
                        if vel[dir] > 0 then
 
52
                           vel[dir] = vel[dir] - drag[dir] * elapsed
 
53
                           if vel[dir] < 0 then vel[dir] = 0 end
 
54
                        elseif vel[dir] < 0 then
 
55
                           vel[dir] = vel[dir] + drag[dir] * elapsed
 
56
                           if vel[dir] > 0 then vel[dir] = 0 end
 
57
                        end
 
58
                     end
 
59
                  end
 
60
 
 
61
                  if minVel[dir] and vel[dir] < minVel[dir] then vel[dir] = minVel[dir] end
 
62
                  if maxVel[dir] and vel[dir] > maxVel[dir] then vel[dir] = maxVel[dir] end
 
63
 
 
64
                  if vel[dir] ~= 0 then self[dir] = self[dir] + vel[dir] * elapsed end
 
65
               end,
 
66
   onStartFrame = function (self)
 
67
                     -- this is all in startframe so it happens before
 
68
                     -- physics calc at beginning of update
 
69
 
 
70
                     -- jumping/falling updates could go in EndFrame...
 
71
                     self.falling = self.velocity.y > 0
 
72
                     if self.falling then self.jumping = false end
 
73
                     --print(self.jumping, self.falling)
 
74
 
 
75
                     if (not self.onGround) and (not self.onWall) then
 
76
                        self:play('jump')
 
77
                     end
 
78
 
 
79
                     self.acceleration.y = 800
 
80
 
 
81
                     if self.onWall then
 
82
                        self.acceleration.y = 0
 
83
 
 
84
                        if the.keys:pressed('up') then
 
85
                           self.velocity.y = -200
 
86
                           self:play('stand')
 
87
                        elseif the.keys:pressed('down') then
 
88
                           self.velocity.y = 200
 
89
                           self:play('stand')
 
90
                        else
 
91
                           self.velocity.y = 0
 
92
                           self:play('stand')
 
93
                        end
 
94
                     end
 
95
 
 
96
                     if the.keys:pressed('left') then
 
97
                        self.velocity.x = -200
 
98
                        if self.onGround then self:play('walk') end
 
99
                        if self.onWall == 'right' then self.onWall = false end
 
100
                     elseif the.keys:pressed('right') then
 
101
                        self.velocity.x = 200
 
102
                        if self.onGround then self:play('walk') end
 
103
                        if self.onWall == 'left' then self.onWall = false end
 
104
                     else
 
105
                        if self.onGround then self:play('stand') end
 
106
                        if not self.onWall then
 
107
                           self.velocity.x = 0
 
108
                        end
 
109
                     end
 
110
 
 
111
                     if the.keys:justPressed('up') and self.onGround then
 
112
                        self.velocity.y = -400
 
113
                        self.jumping = true
 
114
                     end
 
115
                  end,
 
116
   update = function (self, elapsed)
 
117
               -- NOTE: this is an override, not a callback
 
118
 
 
119
               self:doPhysics('x', elapsed)
 
120
               self:collide(the.view.map)
 
121
 
 
122
               -- handle X collisions
 
123
               self.onWall = false
 
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
 
129
                     self.onWall = 'left'
 
130
                  else
 
131
                     print 'x ??'
 
132
                  end
 
133
               end
 
134
 
 
135
               self.onGround = false -- right before Y collision callbacks
 
136
               self:doPhysics('y', elapsed)
 
137
               self:collide(the.view.map)
 
138
 
 
139
               -- handle Y collisions
 
140
               for _, col in ipairs(self.collisions) do
 
141
                  if self.velocity.y > 0 then
 
142
                     self.onGround = true
 
143
                  end
 
144
 
 
145
                  col.other:displaceDir(self, 'y')
 
146
                  self.velocity.y = 0
 
147
                  self.jumping = false
 
148
               end
 
149
 
 
150
               Animation.update(self, elapsed)
 
151
            end,
 
152
   collide = function (self, ...)
 
153
                self.collisions = {}
 
154
                Animation.collide(self, ...)
 
155
                -- I could return a true/false value here if I wanted to...
 
156
             end,
 
157
   onCollide = function (self, other, xOverlap, yOverlap)
 
158
                  if other == the.view.map then return end
 
159
 
 
160
                  table.insert(self.collisions, {other = other,
 
161
                                                 xOverlap = xOverlap,
 
162
                                                 yOverlap = yOverlap })
 
163
               end
 
164
}
 
165
 
 
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
 
170
 
 
171
   if other.sprites then
 
172
      -- handle groups
 
173
 
 
174
      for _, spr in pairs(other.sprites) do
 
175
         self:displace(spr, dir)
 
176
      end
 
177
   else
 
178
      -- handle sprites
 
179
      local dim
15
180
      if dir == 'x' then
16
 
         return 'width'
 
181
         dim = 'width'
17
182
      elseif dir == 'y' then
18
 
         return 'height'
19
 
      else
20
 
         if STRICT then error('dir '..dir) end
 
183
         dim = 'height'
 
184
      else
 
185
         print 'dir ??'
 
186
      end
 
187
 
 
188
      local negMove = (other[dir] - self[dir]) + other[dim]
 
189
      local posMove = (self[dir] + self[dim]) - other[dir]
 
190
 
 
191
      -- TODO: re-add hinting?
 
192
      if negMove < posMove then
 
193
         chg = - negMove
 
194
      else
 
195
         chg = posMove
21
196
      end
22
197
   end
23
 
}
 
198
 
 
199
   other[dir] = other[dir] + chg
 
200
end
24
201
 
25
202
GameView = View:extend {
26
203
   onNew = function (self)
27
204
              self:loadLayers('data/map.lua')
28
205
              self.focus = the.player
29
206
              self:clampTo(self.map)
30
 
 
31
 
              the.recorder = Recorder:new{mousePosInterval = 9999}
32
 
              the.app.meta:add(the.recorder)
33
 
              if the.app.record then
34
 
                 the.recorder:startRecording()
35
 
              elseif the.app.playback then
36
 
                 local storage = Storage:new{filename = 'record.lua'}
37
 
                 storage:load()
38
 
                 --print(inspect(storage.data))
39
 
                 the.recorder.record = storage.data
40
 
                 the.recorder:startPlaying()
41
 
              end
42
207
           end,
43
208
   onUpdate = function (self)
44
 
                 --print('drawTook: ', the.drawTook)
45
209
                 --print('tick')
46
210
                 --the.player:collide(self.map)
47
211
                 --self.map:collide(the.player)
48
 
              end,
49
 
   -- draw = function (self, x, y)
50
 
   --           View.draw(self, x, y)
51
 
 
52
 
   --           love.graphics.print('FPS:' .. love.timer.getFPS(), 20, 20)
53
 
   --        end
 
212
              end
54
213
}
55
214
 
56
215
the.app = App:new {
57
 
   record = true,
58
216
   onRun = function (self)
59
217
              self.view = GameView:new()
60
 
              if DEBUG then
61
 
                 self.console:watch('onGround', 'the.player.onGround')
62
 
                 self.console:watch('onWall', 'the.player.onWall')
63
 
                 self.console:watch('updateTook', 'the.updateTook')
64
 
                 self.console:watch('drawTook', 'the.drawTook')
65
 
                 self.console:watch('recorder state', 'the.recorder.state')
66
 
              end
67
 
 
68
 
              --the.profiler = newProfiler('time', 2000)
69
 
              --the.profiler = newProfiler()
70
 
              --the.profiler:start()
 
218
              self.console:watch('onGround', 'the.player.onGround')
 
219
              self.console:watch('onWall', 'the.player.onWall')
71
220
           end,
72
221
   onUpdate = function (self, dt)
73
 
                 if the.keys:justPressed('escape') then
74
 
                    if the.profiler then
75
 
                       the.profiler:stop()
76
 
                       local outfile = io.open( "profile.txt", "w+" )
77
 
                       the.profiler:report( outfile )
78
 
                       outfile:close()
79
 
                    end
80
 
 
81
 
                    if self.record then
82
 
                       if not love.filesystem.remove('record.lua') then
83
 
                          print('could not remove record.lua')
84
 
                       end
85
 
                       local storage = Storage:new{
86
 
                          data = the.recorder.record,
87
 
                          filename = 'record.lua'
88
 
                       }
89
 
                       storage:save(false)
90
 
                       --print(inspect(the.recorder.record))
91
 
                    end
92
 
 
 
222
                 if the.keys:justPressed('escape') and 
 
223
                   not self.console.visible then
93
224
                    self.quit()
94
225
                 end
95
 
              end,
96
 
   update = function (self, dt)
97
 
               the.updateStart = love.timer.getMicroTime()
98
 
               App.update(self, dt)
99
 
               if the.updateStart then
100
 
                  the.updateTook = love.timer.getMicroTime() - the.updateStart
101
 
               end
102
 
            end
103
 
}
104
 
 
105
 
function love.load (arg)
106
 
   opts = getopt(arg, '')
107
 
   if opts['p'] then
108
 
      the.app.playback = true
109
 
      the.app.record = false
110
 
   elseif opts['r'] then
111
 
      the.app.record = true
112
 
   end
113
 
 
114
 
   the.app:run()
115
 
end
 
 
b'\\ No newline at end of file'
 
226
              end
 
227
}
 
 
b'\\ No newline at end of file'