Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Linux support and resolution/fullscreen support #1

Merged
merged 12 commits into from about 1 year ago

1 participant

Dennis Schneider
Dennis Schneider
Owner
  • Adds linux support for bundle.sh
  • Adds fullscreen support
  • Adds resolution support
  • Various code improvements
  • Settings are now saved in home directory
  • Library updates
Dennis Schneider dschneider merged commit 006b55f into from April 04, 2013
Dennis Schneider dschneider closed this April 04, 2013
Dennis Schneider dschneider deleted the branch April 04, 2013
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.

Showing 34 changed files with 585 additions and 199 deletions. Show diff stats Hide diff stats

  1. 1  .gitignore
  2. BIN  bin/lava-temple.love
  3. 7  bundle.sh
  4. BIN  levels/level_one.png
  5. 20  lib/core/camera.lua
  6. 7  lib/core/effects.lua
  7. 11  lib/core/hud.lua
  8. 2  lib/core/server.lua
  9. 50  lib/core/settings.lua
  10. 49  lib/core/world.lua
  11. 16  lib/entities/chest.lua
  12. 30  lib/entities/lava.lua
  13. 37  lib/entities/platform.lua
  14. 16  lib/entities/player.lua
  15. 30  lib/entities/ruby.lua
  16. 88  lib/states/game.lua
  17. 64  lib/states/graphics_menu.lua
  18. 4  lib/states/main_menu.lua
  19. 43  lib/states/pause_menu.lua
  20. 6  lib/vendor/lumos/base.lua
  21. 2  lib/vendor/quickie/button.lua
  22. 18  lib/vendor/quickie/checkbox.lua
  23. 21  lib/vendor/quickie/core.lua
  24. 14  lib/vendor/quickie/group.lua
  25. 11  lib/vendor/quickie/input.lua
  26. 22  lib/vendor/quickie/keyboard.lua
  27. 4  lib/vendor/quickie/label.lua
  28. 19  lib/vendor/quickie/mouse.lua
  29. 4  lib/vendor/quickie/slider.lua
  30. 10  lib/vendor/quickie/slider2d.lua
  31. 33  lib/vendor/quickie/style-default.lua
  32. 134  lib/vendor/table/table.lua
  33. 11  main.lua
  34. 0  vendor/quickie/init.lua b/lib/vendor/quickie/init.lua
1  .gitignore
... ...
@@ -0,0 +1 @@
  1
+bin/
BIN  bin/lava-temple.love
Binary file not shown
7  bundle.sh
... ...
@@ -1,3 +1,4 @@
  1
+#!/bin/bash
1 2
 # LÖVE Boilerplate - A template for the LÖVE framework (love2d)
2 3
 
3 4
 # Bundle file
@@ -39,4 +40,8 @@ rm bin/$current_dir.love
39 40
 zip -r bin/$current_dir.love *
40 41
 
41 42
 # Start the love app
42  
-/Applications/love0.8.0.app/Contents/MacOS/love bin/$current_dir.love
  43
+unamestr=`uname`
  44
+if [ "$unamestr" == 'Linux' ];
  45
+  then /usr/bin/love bin/$current_dir.love
  46
+  else /Applications/love0.8.0.app/Contents/MacOS/love bin/$current_dir.love
  47
+fi
BIN  levels/level_one.png
20  lib/core/camera.lua
@@ -46,16 +46,24 @@ function Camera:new(x, y, scale_x, scale_y, rotation, object)
46 46
   setmetatable(object, self)
47 47
   self.__index = self -- self refers to Camera here
48 48
 
49  
-  object.x = x
50  
-  object.y = y
51  
-  object.scale_x = scale_x or 1
52  
-  object.scale_y = scale_y or 1
  49
+  object.x        = x
  50
+  object.y        = y
  51
+  object.scale_x  = scale_x or 1
  52
+  object.scale_y  = scale_y or 1
53 53
   object.rotation = rotation or 0
54  
-  object.layers = {}
  54
+  object.layers   = {}
55 55
 
56 56
   return object
57 57
 end
58 58
 
  59
+--Puts the camera into the center of the world, relative to the level size and
  60
+--the current screen resolution.
  61
+function Camera:centerInWorld(width)
  62
+  x_res  = love.graphics.getWidth()
  63
+  center = ((x_res - width) / 2) * (-1)
  64
+  self:setPosition(center, nil)
  65
+end
  66
+
59 67
 function Camera:set()
60 68
   love.graphics.push()
61 69
   love.graphics.rotate(-self.rotation)
@@ -111,7 +119,7 @@ end
111 119
 
112 120
 function Camera:drawLayers()
113 121
   local bx, by = self.x, self.y
114  
-  
  122
+
115 123
   for key, layer in ipairs(self.layers) do
116 124
     self.x = bx * layer.scale
117 125
     self.y = by * layer.scale
7  lib/core/effects.lua
... ...
@@ -1,6 +1,6 @@
1 1
 effects = {}
2 2
 
3  
-local image = love.graphics.newImage("media/images/effects/cloud.png")
  3
+local image  = love.graphics.newImage("media/images/effects/cloud.png")
4 4
 effects.jump = love.graphics.newParticleSystem(image, 1000)
5 5
 effects.jump:setEmissionRate(50)
6 6
 effects.jump:setSizes(0.2, 0.2)
@@ -14,7 +14,10 @@ effects.jump:stop()
14 14
 
15 15
 -- create layer of smoke
16 16
 effects.smoke = {}
17  
-for i = 1, 10 do table.insert(effects.smoke, love.graphics.newParticleSystem(image, 1000)) end
  17
+number_of_smoke = love.graphics.getWidth() / 50
  18
+for i = 1, number_of_smoke do
  19
+  table.insert(effects.smoke, love.graphics.newParticleSystem(image, 1000))
  20
+end
18 21
 
19 22
 for key, smoke_effect in ipairs(effects.smoke) do
20 23
   smoke_effect:setBufferSize(500)
11  lib/core/hud.lua
@@ -28,7 +28,7 @@ function Hud:drawLives()
28 28
   for i = player.lives, 1, -1 do
29 29
     table.insert(lives, Life:new(10 + counter * 3, 25))
30 30
     counter = counter + 10
31  
-  end 
  31
+  end
32 32
 
33 33
   for key, life in ipairs(lives) do
34 34
     life:draw()
@@ -38,6 +38,15 @@ end
38 38
 function Hud:drawRelativeMessages()
39 39
   self:drawDanger()
40 40
   self:drawServerMessages()
  41
+
  42
+  if Settings.draw_fps then
  43
+    self:drawFPS()
  44
+  end
  45
+end
  46
+
  47
+function Hud:drawFPS()
  48
+  fps = love.timer.getFPS()
  49
+  love.graphics.print(fps, camera.x + love.graphics.getWidth() - 130, camera.y + love.graphics.getHeight() - 100)
41 50
 end
42 51
 
43 52
 function Hud:drawDanger()
2  lib/core/server.lua
@@ -9,7 +9,7 @@ local function connected(client_id)
9 9
 end
10 10
 
11 11
 local function receive(data, client_id)
12  
-  if debug then print("SERVER: " .. data) end
  12
+  if Settings.debug then print("SERVER: " .. data) end
13 13
   if data:match("^new_player:client_id:") then
14 14
     server:registerPlayer(data, client_id)
15 15
     server:send(("player_joined:%s"):format(server:getPlayerName(client_id)))
50  lib/core/settings.lua
... ...
@@ -0,0 +1,50 @@
  1
+Settings = {}
  2
+
  3
+local user_path = love.filesystem.getUserDirectory()
  4
+local conf_path = user_path .. "lavatemple.conf"
  5
+local config    = table.load(conf_path)
  6
+
  7
+function Settings.load()
  8
+  if not config then
  9
+    Settings.x_res      = 1024
  10
+    Settings.y_res      = 768
  11
+    Settings.fullscreen = 0
  12
+    Settings.shadows    = 1
  13
+    Settings.fsaa       = 0
  14
+    Settings.vsync      = 1
  15
+    Settings.debug      = 0
  16
+    Settings.draw_fps   = 0
  17
+
  18
+    table.save(Settings, conf_path)
  19
+  else
  20
+    for key, value in pairs(config) do
  21
+      if value == 1 then
  22
+        Settings[key] = true
  23
+      elseif value == 0 then
  24
+        Settings[key] = false
  25
+      end
  26
+    end
  27
+
  28
+    Settings.fsaa  = config.fsaa
  29
+    Settings.x_res = config.x_res
  30
+    Settings.y_res = config.y_res
  31
+  end
  32
+end
  33
+
  34
+function Settings.save()
  35
+  local settings = {}
  36
+
  37
+  for key, value in pairs(Settings) do
  38
+    if value == true then
  39
+      settings[key] = 1
  40
+    elseif value == false then
  41
+      settings[key] = 0
  42
+    else
  43
+      settings[key] = value
  44
+    end
  45
+  end
  46
+
  47
+  table.save(settings, conf_path)
  48
+end
  49
+
  50
+Settings.load()
49  lib/core/world.lua
@@ -8,10 +8,10 @@ function World:new(level_number, object)
8 8
   self.__index = self -- self refers to Camera here
9 9
 
10 10
   object.structureImage = love.image.newImageData("levels/level_" .. level_number .. ".png")
11  
-  object.rubies = {}
12  
-  object.chests = {}
13  
-  object.platforms = {}
14  
-  object.players = {}
  11
+  object.rubies         = {}
  12
+  object.chests         = {}
  13
+  object.platforms      = {}
  14
+  object.players        = {}
15 15
   object:build()
16 16
 
17 17
   return object
@@ -25,16 +25,20 @@ end
25 25
 function World:draw()
26 26
   self:drawCaveBackground()
27 27
   self:drawGround()
28  
-  self:castShadows()
  28
+
  29
+  if Settings.shadows then self:castShadows() end
  30
+
29 31
   self:drawRubies()
30 32
   self:drawPlatforms()
31 33
   self:drawChests()
32 34
   player:draw()
33  
-  if second_player then 
  35
+
  36
+  if second_player then
34 37
     second_player:draw()
35 38
     player:drawName()
36 39
     second_player:drawName()
37 40
   end
  41
+
38 42
   lava:draw()
39 43
 end
40 44
 
@@ -42,35 +46,38 @@ function World:registerPlayer(player)
42 46
   table.insert(self.players, player)
43 47
 end
44 48
 
  49
+--a level is 900px wide
45 50
 function World:build()
  51
+  local block_size = 50
  52
+
46 53
   for x = 0, self.structureImage:getWidth() - 1 do
47 54
     for y = 0, self.structureImage:getHeight() - 1 do
48 55
       local red, green, blue, alpha = self.structureImage:getPixel(x, y)
49 56
 
50 57
       -- It's calculating x and y from the top right image corner
51 58
       -- We turn it around so that it builds the map from the bottom up
52  
-      local x_location_in_world = x * 50
53  
-      local y_location_in_world = (self.structureImage:getHeight() - y) * 50 * (-1)
  59
+      local x_location_in_world = x * block_size
  60
+      local y_location_in_world = (self.structureImage:getHeight() - y) * block_size * (-1)
54 61
 
55 62
       if red == 153 and green == 0 and blue == 0 and alpha == 255 then
56  
-        table.insert(self.platforms, Platform:new(x_location_in_world, y_location_in_world, "one"))
  63
+        table.insert(self.platforms, Platform:new(self, x_location_in_world, y_location_in_world, "one"))
57 64
       elseif red == 0 and green == 153 and blue == 0 and alpha == 255 then
58  
-        table.insert(self.platforms, Platform:new(x_location_in_world, y_location_in_world, "two"))
  65
+        table.insert(self.platforms, Platform:new(self, x_location_in_world, y_location_in_world, "two"))
59 66
       elseif red == 0 and green == 0 and blue == 153 and alpha == 255 then
60  
-        table.insert(self.platforms, Platform:new(x_location_in_world, y_location_in_world, "three"))
  67
+        table.insert(self.platforms, Platform:new(self, x_location_in_world, y_location_in_world, "three"))
61 68
       elseif red == 100 and green == 10 and blue == 0 and alpha == 255 then
62  
-        local ruby = Ruby:new(x_location_in_world, y_location_in_world)
  69
+        local ruby = Ruby:new(self, x_location_in_world, y_location_in_world)
63 70
         --every block has 50 * 50 pixels - that's why we need to get the ruby to the bottom
64 71
         ruby.y = ruby.y + 40 - ruby:getHeight()
65 72
         ruby.x = ruby.x + 40
66 73
         table.insert(self.rubies, ruby)
67 74
       elseif red == 100 and green == 50 and blue == 0 and alpha == 255 then
68  
-        local chest = Chest:new(x_location_in_world, y_location_in_world)
  75
+        local chest = Chest:new(self, x_location_in_world, y_location_in_world)
69 76
         chest.y = chest.y + 50 - chest:getHeight()
70 77
         chest.x = chest.x + 40
71 78
         table.insert(self.chests, chest)
72 79
       elseif red == 0 and green == 0 and blue == 0 and alpha == 255 then
73  
-        player = Player:new(x_location_in_world, y_location_in_world, "default", "blue")
  80
+        player = Player:new(self, x_location_in_world, y_location_in_world, "default", "blue")
74 81
         -- register player in world's player table (necessary for multiplayer)
75 82
         self:registerPlayer(player)
76 83
       end
@@ -79,25 +86,25 @@ function World:build()
79 86
   end
80 87
 
81 88
   -- draw cave background
82  
-  self.cave_quad = love.graphics.newQuad(1, 1, 4000, 10000, 296, 296)
  89
+  self.cave_quad  = love.graphics.newQuad(-400, 1, 4000, 10000, 296, 296)
83 90
   self.background = love.graphics.newImage("media/images/entities/cave.png")
84 91
   self.background:setWrap("repeat", "repeat")
85 92
 
86 93
   -- draw ground floor
87  
-  self.ground_quad = love.graphics.newQuad(1, 1, 4000, 1000, 160 * 5, 96 * 5)
88  
-  self.ground = love.graphics.newImage("media/images/entities/ground.png")
  94
+  self.ground_quad = love.graphics.newQuad(-400, 1, 4000, 1000, 160 * 5, 96 * 5)
  95
+  self.ground      = love.graphics.newImage("media/images/entities/ground.png")
89 96
   self.ground:setWrap("repeat", "clamp")
90 97
 
91 98
   -- create the lava
92  
-  lava = Lava:new(0, 400)
  99
+  lava = Lava:new(-400, 400)
93 100
 end
94 101
 
95 102
 function World:drawCaveBackground()
96  
-  love.graphics.drawq(self.background, self.cave_quad, 0, -5000, 0, 1, 1, 1, 0)
  103
+  love.graphics.drawq(self.background, self.cave_quad, -400, -5000, 0, 1, 1, 1, 0)
97 104
 end
98 105
 
99 106
 function World:drawGround()
100  
-  love.graphics.drawq(self.ground, self.ground_quad, 0, 45, 0, 1, 1, 1, 0)
  107
+  love.graphics.drawq(self.ground, self.ground_quad, -400, 45, 0, 1, 1, 1, 0)
101 108
 end
102 109
 
103 110
 function World:drawRubies()
@@ -115,7 +122,7 @@ end
115 122
 function World:castShadows()
116 123
   for key, platform in ipairs(self.platforms) do player.light:castShadow(platform) end
117 124
   for key, ruby in ipairs(self.rubies) do player.light:castShadow(ruby) end
118  
-  for key, chest in ipairs(self.chests) do player.light:castShadow(chest) end  
  125
+  for key, chest in ipairs(self.chests) do player.light:castShadow(chest) end
119 126
 end
120 127
 
121 128
 function World:removeRuby(key)
16  lib/entities/chest.lua
... ...
@@ -1,19 +1,19 @@
1 1
 Chest = {}
2 2
 
3  
-function Chest:new(x, y, object)
  3
+function Chest:new(world, x, y, object)
4 4
   if not love then print "This library requires Love2D"; return false; end
5 5
 
6 6
   object = object or {} -- create object if user does not provide one
7 7
   setmetatable(object, self)
8 8
   self.__index = self -- self refers to Camera here
9 9
 
10  
-  object.x = x
11  
-  object.y = y
12  
-  object.scaling = 2.0
13  
-  object.image = love.graphics.newImage("media/images/entities/chest.png")
14  
-  object.width = object.image:getWidth() * object.scaling
15  
-  object.height = object.image:getHeight() * object.scaling
16  
-  object.top_edge = object.y
  10
+  object.x           = x
  11
+  object.y           = y
  12
+  object.scaling     = 2.0
  13
+  object.image       = love.graphics.newImage("media/images/entities/chest.png")
  14
+  object.width       = object.image:getWidth() * object.scaling
  15
+  object.height      = object.image:getHeight() * object.scaling
  16
+  object.top_edge    = object.y
17 17
   object.bottom_edge = object.y + 10
18 18
 
19 19
   return object
30  lib/entities/lava.lua
@@ -7,25 +7,33 @@ function Lava:new(x, y, speed, object)
7 7
   setmetatable(object, self)
8 8
   self.__index = self -- self refers to Camera here
9 9
 
10  
-  object.x = x
11  
-  object.y = y
12  
-  object.scaling = 6
13  
-  object.speed = speed or 20
14  
-  object.image_data = love.image.newImageData("media/images/entities/lava.png")
15  
-  object.image = love.graphics.newImage("media/images/entities/lava.png")
16  
-  object.glow_image = love.graphics.newImage("media/images/entities/lava.png")
17  
-  object.width = object.image:getWidth() * object.scaling
18  
-  object.height = object.image:getHeight() * object.scaling
19  
-  object.top_edge = object:getY()
  10
+  object.x           = x
  11
+  object.y           = y
  12
+  object.scaling     = 6
  13
+  object.speed       = speed or 20
  14
+  object.image_data  = love.image.newImageData("media/images/entities/lava.png")
  15
+  object.image       = love.graphics.newImage("media/images/entities/lava.png")
  16
+
  17
+  width  = object.image:getWidth()
  18
+  height = object.image:getHeight()
  19
+  x_res  = love.graphics.getWidth()
  20
+  y_res  = love.graphics.getHeight()
  21
+
  22
+  object.width       = width * object.scaling
  23
+  object.height      = height * object.scaling
  24
+  object.lava_quad   = love.graphics.newQuad(object.x, object.y, x_res, y_res, width, height)
  25
+  object.top_edge    = object:getY()
20 26
   object.bottom_edge = object:getY() + 10
21 27
   object.glow_shader = GlowShader:new()
22 28
 
  29
+  object.image:setWrap("repeat", "repeat")
  30
+
23 31
   return object
24 32
 end
25 33
 
26 34
 function Lava:draw()
27 35
   self.glow_shader:start()
28  
-  love.graphics.draw(self.image, self.x, self.y, 0, self.scaling, self.scaling, 0, 0)
  36
+  love.graphics.drawq(self.image, self.lava_quad, self.x, self.y, 0, self.scaling, self.scaling, 0, 0)
29 37
   love.graphics.setPixelEffect()
30 38
 end
31 39
 
37  lib/entities/platform.lua
... ...
@@ -1,19 +1,19 @@
1 1
 Platform = {}
2 2
 
3  
-function Platform:new(x, y, platform_type, object)
  3
+function Platform:new(world, x, y, platform_type, object)
4 4
   if not love then print "This library requires Love2D"; return false; end
5 5
 
6  
-  object = object or {} -- create object if user does not provide one
  6
+  object = object or {}
7 7
   setmetatable(object, self)
8  
-  self.__index = self -- self refers to Camera here
9  
-
10  
-  object.x = x
11  
-  object.y = y
12  
-  object.scaling = 1.5
13  
-  object.image = love.graphics.newImage("media/images/entities/platform_" .. platform_type .. ".png")
14  
-  object.width = object.image:getWidth() * object.scaling
15  
-  object.height = object.image:getHeight() * object.scaling
16  
-  object.top_edge = object:getY()
  8
+  self.__index = self
  9
+
  10
+  object.x           = x
  11
+  object.y           = y
  12
+  object.scaling     = 1.5
  13
+  object.image       = love.graphics.newImage("media/images/entities/platform_" .. platform_type .. ".png")
  14
+  object.width       = object.image:getWidth() * object.scaling
  15
+  object.height      = object.image:getHeight() * object.scaling
  16
+  object.top_edge    = object:getY()
17 17
   object.bottom_edge = object:getY() + 15
18 18
 
19 19
   return object
@@ -21,10 +21,11 @@ end
21 21
 
22 22
 function Platform:draw()
23 23
   love.graphics.draw(self.image, self.x, self.y, 0, self.scaling, self.scaling, 0, 0)
24  
-  if debug == true then 
25  
-    love.graphics.rectangle( "line", self.x, self.y, self.width, self.height )
26  
-    love.graphics.rectangle( "line", self.x, self.top_edge, self.width, 0.1 )
27  
-    love.graphics.rectangle( "line", self.x, self.bottom_edge, self.width, 0.1 )
  24
+
  25
+  if Settings.debug then
  26
+    love.graphics.rectangle("line", self.x, self.y, self.width, self.height)
  27
+    love.graphics.rectangle("line", self.x, self.top_edge, self.width, 0.1)
  28
+    love.graphics.rectangle("line", self.x, self.bottom_edge, self.width, 0.1)
28 29
   end
29 30
 end
30 31
 
@@ -34,9 +35,9 @@ end
34 35
 
35 36
 function Platform:intersects(player)
36 37
   return player:getCenter() <= (self:getX() + self:getWidth()) and
37  
-  player:getCenter() > self:getX() and
38  
-  player:getBottomEdge() > self.top_edge and
39  
-  player:getBottomEdge() < self.bottom_edge
  38
+    player:getCenter() > self:getX() and
  39
+    player:getBottomEdge() > self.top_edge and
  40
+    player:getBottomEdge() < self.bottom_edge
40 41
 end
41 42
 
42 43
 inherit(Platform, Base)
16  lib/entities/player.lua
... ...
@@ -1,6 +1,6 @@
1 1
 Player = {}
2 2
 
3  
-function Player:new(x, y, name, color, origin, object)
  3
+function Player:new(world, x, y, name, color, origin, object)
4 4
   if not love then print "This library requires Love2D"; return false; end
5 5
 
6 6
   object = object or {} -- create object if user does not provide one
@@ -10,7 +10,7 @@ function Player:new(x, y, name, color, origin, object)
10 10
   -- TODO: create in extra font class where all fonts are saved
11 11
   name_font = love.graphics.newFont("media/fonts/PressStart2P.ttf", 14)
12 12
 
13  
-  object.name = name or "default"
  13
+  object.name  = name or "default"
14 14
   object.color = color or "blue"
15 15
 
16 16
   -- origin is used to determine whether player is the local player
@@ -45,8 +45,8 @@ function Player:new(x, y, name, color, origin, object)
45 45
   object.images = {}
46 46
   object.images.front = love.graphics.newImage("media/images/player_front.png")
47 47
   object.images.jump = love.graphics.newImage("media/images/player_stand_right.png")
48  
-  object.images.stand_left = love.graphics.newImage("media/images/player_stand_left.png") 
49  
-  object.images.stand_right = love.graphics.newImage("media/images/player_stand_right.png") 
  48
+  object.images.stand_left = love.graphics.newImage("media/images/player_stand_left.png")
  49
+  object.images.stand_right = love.graphics.newImage("media/images/player_stand_right.png")
50 50
   object.images.run_right_animation =  love.graphics.newImage("media/images/player_run_right_anim.png")
51 51
   object.images.run_left_animation =  love.graphics.newImage("media/images/player_run_left_anim.png")
52 52
 
@@ -78,11 +78,11 @@ function Player:draw()
78 78
   else
79 79
     love.graphics.draw(self.images[self.state], self.x, self.y + 3, 0, self.scaling, self.scaling, 0, 0)
80 80
   end
81  
-  
82  
-  if debug == true then 
  81
+
  82
+  if Settings.debug then
83 83
     love.graphics.rectangle( "line", self.x, self.y, self.width, self.height )
84 84
     love.graphics.rectangle( "line", self.x, self.top_edge, self.width, 0.1 )
85  
-    love.graphics.rectangle( "line", self.x, self.bottom_edge, self.width, 0.1 )    
  85
+    love.graphics.rectangle( "line", self.x, self.bottom_edge, self.width, 0.1 )
86 86
   end
87 87
 end
88 88
 
@@ -147,7 +147,7 @@ function Player:jump()
147 147
   self.jumping = true
148 148
   sfx:play("jump")
149 149
   effects.jump:setPosition(self:getCenter(), self:getBottomEdge())
150  
-  effects.jump:start()  
  150
+  effects.jump:start()
151 151
 end
152 152
 
153 153
 function Player:getLives()
30  lib/entities/ruby.lua
... ...
@@ -1,19 +1,19 @@
1 1
 Ruby = {}
2 2
 
3  
-function Ruby:new(x, y, object)
  3
+function Ruby:new(world, x, y, object)
4 4
   if not love then print "This library requires Love2D"; return false; end
5 5
 
6 6
   object = object or {} -- create object if user does not provide one
7 7
   setmetatable(object, self)
8 8
   self.__index = self -- self refers to Camera here
9 9
 
10  
-  object.x = x
11  
-  object.y = y
12  
-  object.scaling = 1.5
13  
-  object.image = love.graphics.newImage("media/images/entities/ruby.png")
14  
-  object.width = object.image:getWidth() * object.scaling
15  
-  object.height = object.image:getHeight() * object.scaling
16  
-  object.top_edge = object:getY()
  10
+  object.x           = x
  11
+  object.y           = y
  12
+  object.scaling     = 1.5
  13
+  object.image       = love.graphics.newImage("media/images/entities/ruby.png")
  14
+  object.width       = object.image:getWidth() * object.scaling
  15
+  object.height      = object.image:getHeight() * object.scaling
  16
+  object.top_edge    = object:getY()
17 17
   object.bottom_edge = object:getY() + 10
18 18
 
19 19
   return object
@@ -27,17 +27,17 @@ function Ruby:moveTo(object)
27 27
 end
28 28
 
29 29
 function Ruby:isNear(object)
30  
-  return (self:getX() <= (object:getX() + 30) and 
31  
-    self:getX() >= (object:getX() - 30)) and 
32  
-    (self:getY() <= (object:getY() + 30) and 
  30
+  return (self:getX() <= (object:getX() + 30) and
  31
+    self:getX() >= (object:getX() - 30)) and
  32
+    (self:getY() <= (object:getY() + 30) and
33 33
     self:getY() >= (object:getY() - 30))
34 34
 end
35 35
 
36 36
 function Ruby:intersects(player)
37  
-   return (self:getX() <= (player:getX() + 10) and 
38  
-    self:getX() >= (player:getX() - 10)) and 
39  
-    (self:getY() <= (player:getY() + 10) and 
40  
-    self:getY() >= (player:getY() - 10)) 
  37
+   return (self:getX() <= (player:getX() + 10) and
  38
+    self:getX() >= (player:getX() - 10)) and
  39
+    (self:getY() <= (player:getY() + 10) and
  40
+    self:getY() >= (player:getY() - 10))
41 41
 end
42 42
 
43 43
 inherit(Ruby, Base)
88  lib/states/game.lua
@@ -3,27 +3,29 @@ game = Gamestate.new()
3 3
 function game:init()
4 4
   game_font = love.graphics.newFont("media/fonts/PressStart2P.ttf", 40)
5 5
   love.graphics.setFont(game_font)
6  
-  hud = Hud:new()
7  
-  sfx = Sfx:new()
8  
-  camera = Camera:new(0, 0)
9  
-  pause = false
  6
+  hud          = Hud:new()
  7
+  sfx          = Sfx:new()
  8
+  camera       = Camera:new(0, 0)
  9
+  --A level is 900px wide. We put the camera into the center of the level,
  10
+  --depending on the screen resolution.
  11
+  camera:centerInWorld(900)
  12
+  paused       = false
  13
+  game_started = true
10 14
 
11 15
   sfx:setLooping("lava", true)
12 16
   sfx:play("lava")
13 17
 
14 18
   sfx:setLooping("background", true)
15 19
   sfx:play("background")
16  
-
17  
-  game_started = true
18 20
 end
19 21
 
20 22
 function game:enter(previous)
21  
-  world = World:new("one")
  23
+  if previous == main_menu then world = World:new("one") end
22 24
 end
23 25
 
24 26
 function game:shakeScreen(dt)
25 27
   lava_player_distance = Vector:new(lava:getX(), lava:getY()):distance(Vector:new(player:getX(), player:getY()), "number")
26  
-  shake_factor = 70 - (lava_player_distance  / 20)
  28
+  shake_factor         = 70 - (lava_player_distance  / 20)
27 29
 
28 30
   if shake_factor <= 0 then
29 31
     shake_factor = 0
@@ -40,55 +42,57 @@ end
40 42
 
41 43
 function game:gameover()
42 44
   -- TODO : DRAW GAMEOVER
43  
-  -- light.luminosity = 0  
  45
+  -- light.luminosity = 0
44 46
 end
45 47
 
46 48
 function game:update(dt)
47  
-  Timer.update(dt)
  49
+  if world then
  50
+    Timer.update(dt)
48 51
 
49  
-  -- world holds all players, players are accessed via player and second_player
50  
-  -- global variables right now
51  
-  for index, player in pairs(world.players) do
52  
-    player:update(dt)
53  
-  end
  52
+    -- world holds all players, players are accessed via player and second_player
  53
+    -- global variables right now
  54
+    for index, player in pairs(world.players) do player:update(dt) end
54 55
 
55  
-  world:update(dt)
56  
-  player.light:update(dt)
57  
-  effects:update(dt)
  56
+    world:update(dt)
  57
+    player.light:update(dt)
  58
+    effects:update(dt)
58 59
 
59  
-  -- Send player data to server in multiplayer and update the client
60  
-  if client and player then 
61  
-    client:syncPlayerDataWithServer()
62  
-    client:syncLavaDataWithServer()
63  
-    client:update(dt)
64  
-  end
  60
+    -- Send player data to server in multiplayer and update the client
  61
+    if client and player then
  62
+      client:syncPlayerDataWithServer()
  63
+      client:syncLavaDataWithServer()
  64
+      client:update(dt)
  65
+    end
65 66
 
66  
-  -- Move the camera with the player, but only on the y-axis
67  
-  camera:setPosition(0, player:getY() - 500)  
  67
+    -- Move the camera with the player, but only on the y-axis
  68
+    camera:setPosition(nil, player:getY() - 500)
68 69
 
69  
-  -- Game is over if all player lives are gone
70  
-  if player:getLives() <= 0 then self:gameover() end
  70
+    -- Game is over if all player lives are gone
  71
+    if player:getLives() <= 0 then self:gameover() end
71 72
 
72  
-  -- Shake the screen (the closer the lava, the stronger it shakes)
73  
-  if lava and player then self:shakeScreen(dt) end
  73
+    -- Shake the screen (the closer the lava, the stronger it shakes)
  74
+    if lava and player then self:shakeScreen(dt) end
  75
+  end
74 76
 end
75 77
 
76 78
 function game:draw()
77  
-  camera:set()
78  
-  self:drawScreenShake()
79  
-  camera:drawLayers()
80  
-  world:draw()
81  
-  effects:draw()
82  
-  player.light:draw()
83  
-  hud:drawRelativeMessages()
84  
-  camera:unset()
85  
-  hud:draw()
  79
+  if world then
  80
+    camera:set()
  81
+    self:drawScreenShake()
  82
+    camera:drawLayers()
  83
+    world:draw()
  84
+    effects:draw()
  85
+    player.light:draw()
  86
+    hud:drawRelativeMessages()
  87
+    camera:unset()
  88
+    hud:draw()
  89
+  end
86 90
 end
87 91
 
88 92
 function game:keypressed(key, code)
89  
-  if key == "f" then
90  
-    love.graphics.setMode(1440, 900, false, true, 0)
91  
-    love.graphics.toggleFullscreen()
  93
+  if key == "escape" then
  94
+    paused = not paused
  95
+    Gamestate.switch(pause_menu)
92 96
   elseif key == "s" then
93 97
     game_started = not game_started
94 98
   end
64  lib/states/graphics_menu.lua
... ...
@@ -0,0 +1,64 @@
  1
+graphics_menu = Gamestate.new()
  2
+
  3
+function graphics_menu:init()
  4
+  -- group defaults
  5
+  gui.group.default.size[1] = 150
  6
+  gui.group.default.size[2] = 25
  7
+  gui.group.default.spacing = 5
  8
+
  9
+  modes = love.graphics.getModes()
  10
+end
  11
+
  12
+function graphics_menu:enter(previous)
  13
+
  14
+end
  15
+
  16
+function graphics_menu:change_mode(x, y)
  17
+  love.graphics.setMode(x, y, Settings.fullscreen, Settings.vsync, Settings.fsaa)
  18
+  Settings.x_res = x
  19
+  Settings.y_res = y
  20
+  --A level is 900px wide. We put the camera into the center of the level,
  21
+  --depending on the screen resolution.
  22
+  camera:centerInWorld(900)
  23
+  Settings.save()
  24
+end
  25
+
  26
+function graphics_menu:update(dt)
  27
+  gui.group.push{grow = "down", pos = {(love.graphics.getWidth() / 2) - 130, 200}}
  28
+
  29
+  if gui.Button{text = "Back"} then
  30
+    Gamestate.switch(pause_menu)
  31
+  end
  32
+
  33
+  if gui.Checkbox{checked = Settings.fullscreen, text = "Fullscreen"} then
  34
+    Settings.fullscreen = not Settings.fullscreen
  35
+    love.graphics.toggleFullscreen()
  36
+    Settings.save()
  37
+  end
  38
+
  39
+  if gui.Checkbox{checked = Settings.shadows, text = "Shadows"} then
  40
+    Settings.shadows = not Settings.shadows
  41
+    Settings.save()
  42
+  end
  43
+
  44
+  --Generate all the resolution buttons.
  45
+  for index, mode in ipairs(modes) do
  46
+    if gui.Button{text = mode.width .. "x" .. mode.height} then
  47
+      self:change_mode(mode.width, mode.height)
  48
+    end
  49
+  end
  50
+
  51
+  gui.group.pop{}
  52
+end
  53
+
  54
+function graphics_menu:draw()
  55
+  game:draw()
  56
+  gui.core.draw()
  57
+end
  58
+
  59
+function graphics_menu:keypressed(key, code)
  60
+  gui.keyboard.pressed(key, code)
  61
+  if key == "escape" then
  62
+    Gamestate.switch(pause_menu)
  63
+  end
  64
+end
4  lib/states/main_menu.lua
@@ -11,7 +11,7 @@ function main_menu:init()
11 11
   gui.group.default.size[2] = 25
12 12
   gui.group.default.spacing = 5
13 13
 
14  
-  self.lava = Lava:new(0, 0)
  14
+  self.lava = Lava:new(-400, 0)
15 15
 end
16 16
 
17 17
 function main_menu:enter(previous)
@@ -51,7 +51,7 @@ function main_menu:update(dt)
51 51
   gui.Input{info = host_input, size = {300}}
52 52
 
53 53
   gui.Label{text = "Your multiplayer name", size = {70}}
54  
-  gui.Input{info = id_input, size = {300}}    
  54
+  gui.Input{info = id_input, size = {300}}
55 55
 
56 56
   gui.group.pop{}
57 57
 end
43  lib/states/pause_menu.lua
... ...
@@ -0,0 +1,43 @@
  1
+pause_menu = Gamestate.new()
  2
+
  3
+function pause_menu:init()
  4
+  -- group defaults
  5
+  gui.group.default.size[1] = 150
  6
+  gui.group.default.size[2] = 25
  7
+  gui.group.default.spacing = 5
  8
+end
  9
+
  10
+function pause_menu:enter(previous)
  11
+
  12
+end
  13
+
  14
+function pause_menu:update(dt)
  15
+  gui.group.push{grow = "down", pos = {(love.graphics.getWidth() / 2) - 130, 200}}
  16
+
  17
+  if gui.Button{text = "Resume"} then
  18
+    Gamestate.switch(game)
  19
+  end
  20
+
  21
+  if gui.Button{text = "Graphics"} then
  22
+    Gamestate.switch(graphics_menu)
  23
+  end
  24
+
  25
+  if gui.Button{text = "Main Menu"} then
  26
+    Gamestate.switch(main_menu)
  27
+  end
  28
+
  29
+  gui.group.pop{}
  30
+end
  31
+
  32
+function pause_menu:draw()
  33
+  game:draw()
  34
+  gui.core.draw()
  35
+end
  36
+
  37
+function pause_menu:keypressed(key, code)
  38
+  gui.keyboard.pressed(key, code)
  39
+  if key == "escape" then
  40
+    paused = not paused
  41
+    Gamestate.switch(game)
  42
+  end
  43
+end
6  lib/vendor/lumos/base.lua
@@ -92,8 +92,8 @@ function Base:getBottomEdge()
92 92
 end
93 93
 
94 94
 function Base:updateEdges()
95  
-  self.top_edge = self:getY()
  95
+  self.top_edge    = self:getY()
96 96
   self.bottom_edge = self:getY() + self:getHeight()
97  
-  self.left_edge = self:getX()
98  
-  self.right_edge = self:getX() + self:getWidth()
  97
+  self.left_edge   = self:getX()
  98
+  self.right_edge  = self:getX() + self:getWidth()
99 99
 end
2  lib/vendor/quickie/button.lua 100755 → 100644
@@ -48,7 +48,7 @@ return function(w)
48 48
 	end
49 49
 
50 50
 	-- Generate unique identifier for gui state update and querying.
51  
-	local id = core.generateID()
  51
+	local id = w.id or core.generateID()
52 52
 
53 53
 	-- group.getRect determines the position and size of the widget according
54 54
 	-- to the currently active group. Both arguments may be omitted.
18  lib/vendor/quickie/checkbox.lua 100755 → 100644
@@ -29,40 +29,40 @@ local group    = require(BASE .. 'group')
29 29
 local mouse    = require(BASE .. 'mouse')
30 30
 local keyboard = require(BASE .. 'keyboard')
31 31
 
32  
--- {info = {checked = status, label = "", algin = "left"}, pos = {x, y}, size={w, h}, widgetHit=widgetHit, draw=draw}
  32
+-- {checked = status, text = "", algin = "left", pos = {x, y}, size={w, h}, widgetHit=widgetHit, draw=draw}
33 33
 return function(w)
34 34
 	assert(type(w) == "table")
35  
-	w.info.label = w.info.label or ""
  35
+	w.text = w.text or ""
36 36
 
37 37
 	local tight = w.size and (w.size[1] == 'tight' or w.size[2] == 'tight')
38 38
 	if tight then
39 39
 		local f = assert(love.graphics.getFont())
40 40
 		if w.size[1] == 'tight' then
41  
-			w.size[1] = f:getWidth(w.info.label)
  41
+			w.size[1] = f:getWidth(w.text)
42 42
 		end
43 43
 		if w.size[2] == 'tight' then
44  
-			w.size[2] = f:getHeight(w.info.label)
  44
+			w.size[2] = f:getHeight(w.text)
45 45
 		end
46 46
 		-- account for the checkbox
47 47
 		local bw = math.min(w.size[1] or group.size[1], w.size[2] or group.size[2])
48 48
 		w.size[1] = w.size[1] + bw + 4
49 49
 	end
50 50
 
51  
-	local id = core.generateID()
  51
+	local id = w.id or core.generateID()
52 52
 	local pos, size = group.getRect(w.pos, w.size)
53 53
 
54 54
 	mouse.updateWidget(id, pos, size, w.widgetHit)
55 55
 	keyboard.makeCyclable(id)
56 56
 
57  
-	local checked = w.info.checked
  57
+	local checked = w.checked
58 58
 	local key = keyboard.key
59 59
 	if mouse.releasedOn(id) or ((key == 'return' or key == ' ') and keyboard.hasFocus(id)) then
60  
-		w.info.checked = not w.info.checked
  60
+		w.checked = not w.checked
61 61
 	end
62 62
 
63 63
 	core.registerDraw(id, w.draw or core.style.Checkbox,
64  
-		w.info.checked, w.info.label, w.info.align or 'left', pos[1], pos[2], size[1], size[2])
  64
+		w.checked, w.text, w.align or 'left', pos[1], pos[2], size[1], size[2])
65 65
 
66  
-	return w.info.checked ~= checked
  66
+	return w.checked ~= checked
67 67
 end
68 68
 
21  lib/vendor/quickie/core.lua 100755 → 100644
@@ -24,7 +24,6 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
24 24
 THE SOFTWARE.
25 25
 ]]--
26 26
 
27  
-local NO_WIDGET = function()end
28 27
 local BASE = (...):match("(.-)[^%.]+$")
29 28
 local group    = require(BASE .. 'group')
30 29
 local mouse    = require(BASE .. 'mouse')
@@ -54,19 +53,27 @@ local function save_pack(...)
54 53
 	return {n = select('#', ...), ...}
55 54
 end
56 55
 
57  
-local function save_unpack(t, i)
58  
-	i = i or 1
59  
-	if i >= t.n then return t[i] end
60  
-	return t[i], save_unpack(t, i+1)
  56
+local function save_unpack_helper(t, i, ...)
  57
+	if i <= 0 then return ... end
  58
+	return save_unpack_helper(t, i-1, t[i], ...)
  59
+end
  60
+
  61
+local function save_unpack(t)
  62
+	return save_unpack_helper(t, t.n)
61 63
 end
62 64
 
63 65
 --
64 66
 -- Widget ID
65 67
 --
66  
-local maxid = 0
  68
+local maxid, uids = 0, {}
  69
+setmetatable(uids, {__index = function(t, i)
  70
+	t[i] = {}
  71
+	return t[i]
  72
+end})
  73
+
67 74
 local function generateID()
68 75
 	maxid = maxid + 1
69  
-	return maxid
  76
+	return uids[maxid]
70 77
 end
71 78
 
72 79
 --
14  lib/vendor/quickie/group.lua 100755 → 100644
@@ -138,6 +138,14 @@ return setmetatable({
138 138
 	beginFrame = beginFrame,
139 139
 	endFrame   = endFrame,
140 140
 	default    = default,
141  
-}, {__index = function(_,k) 
142  
-	return ({size = current.size, pos = current.pos})[k]
143  
-end})
  141
+}, {
  142
+	__index = function(_,k)
  143
+		return ({size = current.size, pos = current.pos})[k]
  144
+	end,
  145
+	__call = function(_, info)
  146
+		assert(type(info) == 'table' and type(info[1]) == 'function')
  147
+		push(info)
  148
+		info[1]()
  149
+		pop()
  150
+	end,
  151
+})
11  lib/vendor/quickie/input.lua 100755 → 100644
@@ -36,24 +36,21 @@ return function(w)
36 36
 	w.info.text = w.info.text or ""
37 37
 	w.info.cursor = math.min(w.info.cursor or w.info.text:len(), w.info.text:len())
38 38
 
39  
-	local id = core.generateID()
  39
+	local id = w.id or core.generateID()
40 40
 	local pos, size = group.getRect(w.pos, w.size)
41 41
 	mouse.updateWidget(id, pos, size, w.widgetHit)
42 42
 	keyboard.makeCyclable(id)
43 43
 	if mouse.isActive(id) then keyboard.setFocus(id) end
44 44
 
45  
-	local changed = false
46 45
 	if not keyboard.hasFocus(id) then
47 46
 		--[[nothing]]
48 47
 	-- editing
49 48
 	elseif keyboard.key == 'backspace' then
50 49
 		w.info.text = w.info.text:sub(1,w.info.cursor-1) .. w.info.text:sub(w.info.cursor+1)
51 50
 		w.info.cursor = math.max(0, w.info.cursor-1)
52  
-		changed = true
53 51
 	elseif keyboard.key == 'delete' then
54 52
 		w.info.text = w.info.text:sub(1,w.info.cursor) .. w.info.text:sub(w.info.cursor+2)
55 53
 		w.info.cursor = math.min(w.info.text:len(), w.info.cursor)
56  
-		changed = true
57 54
 	-- movement
58 55
 	elseif keyboard.key == 'left' then
59 56
 		w.info.cursor = math.max(0, w.info.cursor-1)
@@ -64,16 +61,18 @@ return function(w)
64 61
 	elseif keyboard.key == 'end' then
65 62
 		w.info.cursor = w.info.text:len()
66 63
 	-- info
  64
+	elseif keyboard.key == 'return' then
  65
+		keyboard.clearFocus()
  66
+		keyboard.pressed('', -1)
67 67
 	elseif keyboard.code >= 32 and keyboard.code < 127 then
68 68
 		local left = w.info.text:sub(1,w.info.cursor)
69 69
 		local right =  w.info.text:sub(w.info.cursor+1)
70 70
 		w.info.text = table.concat{left, string.char(keyboard.code), right}
71 71
 		w.info.cursor = w.info.cursor + 1
72  
-		changed = true
73 72
 	end
74 73
 
75 74
 	core.registerDraw(id, w.draw or core.style.Input,
76 75
 		w.info.text, w.info.cursor, pos[1],pos[2], size[1],size[2])
77 76
 
78  
-	return changed
  77
+	return mouse.releasedOn(id) or (keyboard.key == 'return' and keyboard.hasFocus(id))
79 78
 end
22  lib/vendor/quickie/keyboard.lua 100755 → 100644
@@ -26,6 +26,7 @@ THE SOFTWARE.
26 26
 
27 27
 local key,code = nil, -1
28 28
 local focus, lastwidget
  29
+local NO_WIDGET = {}
29 30
 
30 31
 local cycle = {
31 32
 	-- binding = {key = key, modifier1, modifier2, ...} XXX: modifiers are OR-ed!
@@ -33,11 +34,16 @@ local cycle = {
33 34
 	next = {key = 'tab'},
34 35
 }
35 36
 
36  
-local function pressed(...)   key, code = ... end
37  
-local function setFocus(id)   focus = id end
38  
-local function disableFocus() focus = NO_WIDGET end
39  
-local function clearFocus()   focus = nil end
40  
-local function hasFocus(id)   return id == focus end
  37
+local function pressed(...)
  38
+	key, code = ...
  39
+	assert(type(key) == 'string', 'Invalid argument `key`. Expected string, got ' .. type(key))
  40
+	assert(type(code) == 'number', 'Invalid argument `code`. Expected number, got ' .. type(code))
  41
+end
  42
+local function setFocus(id) focus = id end
  43
+local function disable()    focus = NO_WIDGET end
  44
+local function clearFocus() focus = nil end
  45
+local function hasFocus(id) return id == focus end
  46
+local function getFocus()   return focus end
41 47
 
42 48
 local function tryGrab(id)
43 49
 	if not focus then
@@ -78,12 +84,14 @@ return setmetatable({
78 84
 	tryGrab       = tryGrab,
79 85
 	isBindingDown = isBindingDown,
80 86
 	setFocus      = setFocus,
81  
-	disableFocus  = disableFocus,
82  
-	enableFocus   = clearFocus,
  87
+	getFocus      = getFocus,
83 88
 	clearFocus    = clearFocus,
84 89
 	hasFocus      = hasFocus,
85 90
 	makeCyclable  = makeCyclable,
86 91
 
  92
+	disable       = disable,
  93
+	enable        = clearFocus,
  94
+
87 95
 	beginFrame   = beginFrame,
88 96
 	endFrame     = endFrame,
89 97
 }, {__index = function(_,k) return ({key = key, code = code})[k] end})
4  lib/vendor/quickie/label.lua 100755 → 100644
@@ -46,14 +46,14 @@ return function(w)
46 46
 		end
47 47
 	end
48 48
 
49  
-	local id = core.generateID()
  49
+	local id = w.id or core.generateID()
50 50
 	local pos, size = group.getRect(w.pos, w.size)
51 51
 
52 52
 	if keyboard.hasFocus(id) then
53 53
 		keyboard.clearFocus()
54 54
 	end
55 55
 
56  
-	core.registerDraw(id, draw or core.style.Label,
  56
+	core.registerDraw(id, w.draw or core.style.Label,
57 57
 		w.text, w.align, pos[1],pos[2], size[1],size[2])
58 58
 
59 59
 	return mouse.releasedOn(id)
19  lib/vendor/quickie/mouse.lua 100755 → 100644
@@ -29,6 +29,8 @@ local _M -- holds the module. needed to make widgetHit overridable