/traderous

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

« back to all changes in this revision

Viewing changes to main.lua

  • Committer: Josh C
  • Date: 2013-06-15 15:58:55 UTC
  • Revision ID: josh@9ix.org-20130615155855-3i8a1hotsohsi82g
breakĀ outĀ planet

Show diffs side-by-side

added added

removed removed

Lines of Context:
2
2
DEBUG = true
3
3
 
4
4
require 'zoetrope'
5
 
--__ = require 'underscore'
6
5
vector = require 'vector'
 
6
--inspect = require 'inspect'
 
7
 
 
8
require 'group'
7
9
 
8
10
require 'version'
9
11
require 'wrap_tile'
 
12
require 'mirror'
10
13
require 'player'
11
14
require 'enemy'
12
15
require 'cursor'
13
16
require 'bullet'
 
17
require 'rock'
 
18
require 'boom'
 
19
require 'planet'
14
20
 
15
21
util = {
16
22
   signOf = function(value)
19
25
               else
20
26
                  return -1
21
27
               end
22
 
            end
 
28
            end,
 
29
   shortestVector = function(from, to)
 
30
                       if STRICT then
 
31
                          if from.x < the.app.width / 2 or
 
32
                             from.x > the.bg.width - the.app.width / 2 or
 
33
                             from.y < the.app.height / 2 or
 
34
                             from.y > the.bg.height - the.app.height / 2 then
 
35
                             error('"from" coordinate out of bounds: X='..from.x..' Y='..from.y)
 
36
                          end
 
37
 
 
38
                          if to.x < the.app.width / 2 or
 
39
                             to.x > the.bg.width - the.app.width / 2 or
 
40
                             to.y < the.app.height / 2 or
 
41
                             to.y > the.bg.height - the.app.height / 2 then
 
42
                             error('"to" coordinate out of bounds: X='..to.x..' Y='..to.y)
 
43
                          end
 
44
                       end
 
45
 
 
46
                       -- normalize grid to account for mirror zones
 
47
                       local fx = from.x - the.app.width / 2
 
48
                       local fy = from.y - the.app.height / 2
 
49
                       local tx = to.x - the.app.width / 2
 
50
                       local ty = to.y - the.app.height / 2
 
51
 
 
52
                       local short = {}
 
53
 
 
54
                       -- pick shorter x
 
55
                       if math.abs(tx - fx) < math.abs(tx - fx - (the.bg.width - the.app.width)) then
 
56
                          -- straight path is shorter
 
57
                          short.x = tx - fx
 
58
                       else
 
59
                          short.x = tx - fx - (the.bg.width - the.app.width)
 
60
                       end
 
61
 
 
62
                       -- pick shorter y
 
63
                       if math.abs(ty - fy) < math.abs(ty - fy - (the.bg.height - the.app.height)) then
 
64
                          -- straight path is shorter
 
65
                          short.y = ty - fy
 
66
                       else
 
67
                          short.y = ty - fy - (the.bg.height - the.app.height)
 
68
                       end
 
69
 
 
70
                       return vector.new(short.x, short.y)
 
71
                    end
23
72
}
24
73
 
25
74
GameView = View:extend {
 
75
   lastRock = 0,
 
76
   rockInterval = 1,
 
77
   gameStart = 0,
26
78
   onNew = function (self)
27
79
              -- for x = 1,30 do
28
80
              --    for y = 1,30 do
33
85
              --    end
34
86
              -- end
35
87
 
 
88
              the.storage = Storage:new{filename = 'scores.lua'}
 
89
              the.storage:load()
 
90
              if not the.storage.data.highScore then
 
91
                 print('initializing storage')
 
92
                 the.storage.data = {highScore = 0}
 
93
              end
 
94
 
 
95
              --the.rockColliders = Group:new()
 
96
              the.bullets = Group:new()
 
97
              the.mirrors = Group:new()
 
98
              --the.rocks = Group:new()
 
99
              the.interface = Group:new()
 
100
              the.planets = Group:new()
 
101
              the.indicators = Group:new()
 
102
 
36
103
              the.bg = Tile:new{
37
104
                 image = 'data/stars3.png',
38
 
                 -- 1366x768 * 3
39
 
                 width = 4098,
40
 
                 height = 2304
 
105
                 width = 13660,
 
106
                 height = 7680
41
107
              }
42
108
              self:add(the.bg)
43
109
 
 
110
              self:add(the.planets)
 
111
 
44
112
              --the.player = CrystalPlayer:new{x=400,y=300}
45
 
              the.player = SpacePlayer:new{x=1366,y=768}
 
113
              the.player = SpacePlayer:new{x=the.bg.width / 2, y=the.bg.height / 2}
46
114
              self:add(the.player)
47
 
 
48
 
              self:add(Enemy:new{x=400, y=300})
 
115
              self:add(the.player.thrust)
 
116
 
 
117
              --self:add(Enemy:new{x=400, y=300})
 
118
 
 
119
              self:add(the.bullets)
 
120
              --self:add(the.rockColliders)
 
121
              self:add(the.mirrors)
 
122
              --self:add(the.rocks)
 
123
              self:add(the.indicators)
 
124
              self:add(the.interface)
 
125
 
 
126
              for _ = 1, math.random(6) do
 
127
                 local planet = Planet:new{
 
128
                    x = math.random(the.app.width / 2,
 
129
                                    the.bg.width - the.app.width / 2),
 
130
                    y = math.random(the.app.height / 2,
 
131
                                    the.bg.height - the.app.height / 2),
 
132
                    rotation = math.random() * math.pi
 
133
                 }
 
134
                 the.planets:add(planet)
 
135
              end
49
136
 
50
137
              the.cursor = Cursor:new()
51
138
              self:add(the.cursor)
52
139
 
 
140
              the.score = Text:new{
 
141
                 x = 8,
 
142
                 y = 8,
 
143
                 width = the.app.width,
 
144
                 --align = 'center',
 
145
                 font = 25}
 
146
              --the.interface:add(the.score)
 
147
 
 
148
              local hs = the.storage.data.highScore
 
149
              local m = hs / 60
 
150
              local s = hs % 60
 
151
 
 
152
              the.highScore = Text:new{
 
153
                 x = -8,
 
154
                 y = 8,
 
155
                 width = the.app.width,
 
156
                 align = 'right',
 
157
                 font = 25,
 
158
                 text = string.format('High Score: %d:%02d', m, s)
 
159
              }
 
160
              --the.interface:add(the.highScore)
 
161
 
 
162
              the.over = Text:new{
 
163
                 y = the.app.height / 2,
 
164
                 width = the.app.width,
 
165
                 align = 'center',
 
166
                 font = 25,
 
167
                 text = "Game Over",
 
168
                 visible = false
 
169
              }
 
170
              the.interface:add(the.over)
 
171
 
 
172
 
 
173
              the.instructions = Text:new{
 
174
                 y = the.app.height / 2 + 32,
 
175
                 width = the.app.width,
 
176
                 align = 'center',
 
177
                 font = 12,
 
178
                 text = "Press Enter to start a new game\nPress Q to quit",
 
179
                 visible = false
 
180
              }
 
181
              the.interface:add(the.instructions)
 
182
 
53
183
              love.mouse.setGrab(true)
54
184
              love.mouse.setVisible(false)
 
185
              love.mouse.setPosition(the.app.width / 2, the.app.height / 2)
55
186
 
56
187
              --self:loadLayers('data/map.lua')
57
188
              self.focus = the.player
58
189
              --self:clampTo(self.map)
 
190
 
 
191
              self.gameStart = love.timer.getTime()
59
192
           end,
 
193
   onUpdate = function(self, dt)
 
194
                 if false and the.player.active and love.timer.getTime() > self.lastRock + self.rockInterval then
 
195
                    local unseenRock = nil
 
196
                    while not unseenRock do
 
197
                       local rock = Rock:new{
 
198
                          x = math.random(the.app.width / 2,
 
199
                                          the.bg.width - the.app.width / 2),
 
200
                          y = math.random(the.app.height / 2,
 
201
                                          the.bg.height - the.app.height / 2),
 
202
                          velocity = {
 
203
                             x = math.random(-300, 300),
 
204
                             y = math.random(-300, 300),
 
205
                             rotation = math.random(-7, 7)
 
206
                          },
 
207
                          scale = math.random() + 0.5
 
208
                       }
 
209
 
 
210
                       local rockToPlayer = util.shortestVector(rock, the.player)
 
211
                       if math.abs(rockToPlayer.x) > the.app.width / 2 + rock.width * rock.scale and
 
212
                           math.abs(rockToPlayer.y) > the.app.height / 2 + rock.height * rock.scale then
 
213
                         unseenRock = rock
 
214
                        end
 
215
                    end
 
216
 
 
217
                    the.rocks:add(unseenRock)
 
218
 
 
219
                    self.lastRock = love.timer.getTime()
 
220
                 end
 
221
 
 
222
                 the.bullets:collide(the.rockColliders)
 
223
 
 
224
                 -- this should really go somewhere else...
 
225
                 for _, planet in ipairs(the.planets.sprites) do
 
226
                    local indx, indy
 
227
                    local pvec = vector.new(
 
228
                       planet.x - the.player.x + planet.width / 2,
 
229
                       planet.y - the.player.y + planet.height / 2 )
 
230
 
 
231
                    -- TODO: is there a better way to specify the
 
232
                    -- screen rectangle?
 
233
                    if planet:intersects(the.player.x - the.app.width / 2,
 
234
                                         the.player.y - the.app.height / 2,
 
235
                                         the.app.width,
 
236
                                         the.app.height) then
 
237
                       -- planet is on the screen
 
238
                       planet.indicator.visible = false
 
239
                    else
 
240
                       planet.indicator.visible = true
 
241
 
 
242
                       if math.abs(pvec.x) / math.abs(pvec.y) > the.app.width / the.app.height then
 
243
                          indx = (the.app.width / 2 - 10) * util.signOf(pvec.x) + 8
 
244
                          indy = (the.app.width / 2 - 10) * pvec.y / math.abs(pvec.x)
 
245
                       else
 
246
                          indy = (the.app.height / 2 - 10) * util.signOf(pvec.y) + 8
 
247
                          indx = (the.app.height / 2 - 10) * pvec.x / math.abs(pvec.y)
 
248
                       end
 
249
 
 
250
                       planet.indicator.x = the.player.x + indx
 
251
                       planet.indicator.y = the.player.y + indy
 
252
                    end
 
253
                 end
 
254
 
 
255
                 -- for _, mirror in ipairs(the.mirrors.sprites) do
 
256
                 --    if not mirror.of then
 
257
                 --       print('mirror:' .. inspect(mirror))
 
258
                 --       error('mirror OF NOTHING')
 
259
                 --    end
 
260
                 -- end
 
261
              end,
 
262
   onEndFrame = function(self)
 
263
                   the.interface.translate.x = the.player.x - the.app.width / 2 + the.player.width / 2
 
264
                   the.interface.translate.y = the.player.y - the.app.height / 2 + the.player.height / 2
 
265
 
 
266
                   if the.player.active then
 
267
                      self:updateScore()
 
268
                   end
 
269
                end,
60
270
   draw = function (self, x, y)
61
271
             View.draw(self, x, y)
62
 
             love.graphics.print('FPS:' .. love.timer.getFPS(), 20, 20)
63
 
          end
 
272
             --love.graphics.print('FPS:' .. love.timer.getFPS(), 20, 20)
 
273
          end,
 
274
   updateScore = function(self)
 
275
                    local t = love.timer.getTime() - self.gameStart
 
276
                    local m = t / 60
 
277
                    local s = t % 60
 
278
 
 
279
                    the.score.text = string.format('Score: %d:%02d', m, s)
 
280
                    --the.score.y = the.player.y - the.app.height / 2 + the.player.height
 
281
                    --the.score.x = the.player.x - the.app.width / 2 + the.player.width
 
282
 
 
283
                    --the.highScore.y = the.player.y - the.app.height / 2 + the.player.height
 
284
                    --the.highScore.x = the.player.x - the.app.width / 2
 
285
                 end
64
286
}
65
287
 
66
288
MenuScreen = View:extend {
80
302
the.app = App:new {
81
303
   onRun = function (self)
82
304
              print('Version: ' .. VERSION)
 
305
 
 
306
              math.randomseed(os.time())
 
307
 
83
308
              self.view = GameView:new()
 
309
 
84
310
              if DEBUG then
85
311
                 self.console:watch('VERSION', 'VERSION')
86
312
                 self.console:watch('updateTook', 'the.updateTook')
88
314
                 self.console:watch('the.player.y', 'the.player.y')
89
315
                 self.console:watch('the.app.width', 'the.app.width')
90
316
                 self.console:watch('the.app.height', 'the.app.height')
 
317
                 self.console:watch('num mirrors', '#the.mirrors.sprites')
 
318
                 self.console:watch('num rocks', '#the.rocks.sprites')
 
319
                 self.console:watch('num planets', '#the.planets.sprites')
91
320
                 --self.console:watch('drawTook', 'the.drawTook')
92
321
 
93
322
                 -- back off that dark overlay a bit
95
324
              end
96
325
           end,
97
326
   onUpdate = function (self, dt)
98
 
                 if the.keys:justPressed('escape') then
99
 
                    self.quit()
 
327
                 if not (DEBUG and the.console.visible) then
 
328
                    if the.keys:justPressed('q') then
 
329
                       self.quit()
 
330
                    elseif the.keys:justPressed('return') then
 
331
                       if the.keys:pressed('alt') then
 
332
                          love.graphics.toggleFullscreen()
 
333
                       else
 
334
                          self.view = GameView:new()
 
335
                       end
 
336
                    elseif the.keys:justPressed('f1') then
 
337
                       local ss = love.graphics.newScreenshot()
 
338
                       ss:encode('screenshot-' ..love.timer.getTime()..'.png')
 
339
                    elseif the.keys:justPressed('f11') then
 
340
                       love.graphics.toggleFullscreen()
 
341
                    end
100
342
                 end
101
343
              end,
102
344
   update = function (self, dt)
107
349
               end
108
350
            end
109
351
}
 
352
 
 
353
realRun = love.run
 
354
function love.run()
 
355
   -- should fail silently if it can't go to fullscreen...
 
356
   love.graphics.toggleFullscreen()
 
357
 
 
358
   realRun()
 
359
end
 
 
b'\\ No newline at end of file'