menu.lua 8.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292
  1. local tween = require 'lib/deps/tween/tween'
  2. local g = love.graphics
  3. Menu = class()
  4. function Menu:load(user, options, info)
  5. data.load()
  6. -- Initialize UI
  7. self.u, self.v = love.graphics.getDimensions()
  8. self.virtualCursor = VirtualCursor()
  9. self.gooey = Gooey()
  10. -- Initialize pages
  11. self.start = MenuStart()
  12. self.select = MenuUser()
  13. self.choose = MenuChoose()
  14. self.campaign = MenuCampaign()
  15. self.survival = MenuSurvival()
  16. -- Initialize options
  17. if not love.filesystem.exists('save/options.json') then
  18. love.filesystem.createDirectory('save')
  19. love.filesystem.write('save/options.json', json.encode(config.defaultOptions))
  20. end
  21. local str = love.filesystem.read('save/options.json')
  22. self.options = options or json.decode(str)
  23. self.options = self.options or table.copy(config.defaultOptions)
  24. self.optionsPane = MenuOptions()
  25. -- Initialize sound
  26. self.sound = Sound(self.options)
  27. self.menuSounds = self.sound:loop('riteOfPassage')
  28. if self.options and self.options.mute then self.sound:setMute(self.options.mute) end
  29. -- Initialize uv and tooltip
  30. self.tooltip = Tooltip()
  31. self:initAnimations()
  32. -- Initialize backgrounds and canvases
  33. self.backgroundAlpha = 0
  34. self.prevBackgroundAlpha = self.backgroundAlpha
  35. self.background1 = g.newCanvas(self.u, self.v)
  36. self.background2 = g.newCanvas(self.u, self.v)
  37. self.workingCanvas = g.newCanvas(self.u, self.v)
  38. self.unitCanvas = g.newCanvas(400, 400)
  39. self.screenCanvas = g.newCanvas(self.u, self.v)
  40. self.user = user
  41. self.campaign.biome = info and info.biome
  42. self.page = info and info.page or 'start'
  43. self.rewards = (info and info.rewards) or {}
  44. self.rewards.runes = self.rewards.runes or {}
  45. self:setPage(self.page)
  46. if self.page ~= 'start' then self:refreshBackground() end
  47. love.keyboard.setKeyRepeat(true)
  48. end
  49. function Menu:update()
  50. -- Ensure that "Play" can't be clicked while options is open
  51. if self.optionsPane.active then self.campaign.play.disabled = true
  52. else self.campaign.play.disabled = false end
  53. self.tooltip:update()
  54. self.gooey:update()
  55. self.prevBackgroundAlpha = self.backgroundAlpha
  56. self.backgroundAlpha = lume.lerp(self.backgroundAlpha, 1, math.min(8 * ls.tickrate, 1))
  57. self.start:update()
  58. self.select:update()
  59. self.choose:update()
  60. self.campaign:update()
  61. self.survival:update()
  62. self.optionsPane:update()
  63. self.virtualCursor:update()
  64. end
  65. function Menu:draw()
  66. if ls.frame < 3 then
  67. ls.dt = 0
  68. end
  69. self.screenCanvas:clear(0, 0, 0, 0)
  70. self.screenCanvas:renderTo(function()
  71. self.start:draw()
  72. if self.page ~= 'start' then self:drawBackground() end
  73. self.select:draw()
  74. self.choose:draw()
  75. self.campaign:draw()
  76. self.survival:draw()
  77. end)
  78. g.setColor(255, 255, 255)
  79. g.draw(self.screenCanvas)
  80. self.optionsPane:draw()
  81. self.tooltip:draw()
  82. end
  83. function Menu:keypressed(key)
  84. if self.choose:keypressed(key) then return end
  85. end
  86. function Menu:keyreleased(key)
  87. if self.campaign:keyreleased(key) then return end
  88. if self.survival:keyreleased(key) then return end
  89. if self.optionsPane:keyreleased(key) then return end
  90. if self.select:keyreleased(key) then return end
  91. if self.choose:keyreleased(key) then return end
  92. if self.start:keyreleased(key) then return end
  93. if key == 'm' then
  94. self.options.mute = not self.options.mute
  95. self.sound:setMute(self.options.mute)
  96. saveOptions(self.options)
  97. self.optionsPane.refreshControls()
  98. end
  99. end
  100. function Menu:mousemoved(mx, my)
  101. self.tooltip:dirty()
  102. end
  103. function Menu:mousepressed(mx, my, b)
  104. self.gooey:mousepressed(mx, my, b)
  105. if self.optionsPane:mousepressed(mx, my, b) then return end
  106. self.start:mousepressed(mx, my, b)
  107. self.choose:mousepressed(mx, my, b)
  108. self.campaign:mousepressed(mx, my, b)
  109. self.survival:mousepressed(mx, my, b)
  110. end
  111. function Menu:mousereleased(mx, my, b)
  112. self.gooey:mousereleased(mx, my, b)
  113. self.start:mousereleased(mx, my, b)
  114. self.campaign:mousereleased(mx, my, b)
  115. self.survival:mousereleased(mx, my, b)
  116. end
  117. function Menu:gamepadpressed(gamepad, button)
  118. if button == 'a' then
  119. local x, y = love.mouse.getPosition()
  120. self:mousepressed(x, y, 'l')
  121. else
  122. self.start:gamepadpressed(gamepad, button)
  123. self.campaign:gamepadpressed(gamepad, button)
  124. self.optionsPane:gamepadpressed(gamepad, button)
  125. end
  126. end
  127. function Menu:gamepadreleased(gamepad, button)
  128. if button == 'a' then
  129. local x, y = love.mouse.getPosition()
  130. self:mousereleased(x, y, 'l')
  131. end
  132. end
  133. function Menu:gamepadaxis(...)
  134. self.optionsPane:gamepadaxis(...)
  135. end
  136. function Menu:textinput(char)
  137. self.choose:textinput(char)
  138. end
  139. function Menu:resize()
  140. self.u, self.v = g.getDimensions()
  141. self.background1 = g.newCanvas(self.u, self.v)
  142. self.background2 = g.newCanvas(self.u, self.v)
  143. self.workingCanvas = g.newCanvas(self.u, self.v)
  144. self.unitCanvas = g.newCanvas(400, 400)
  145. self.screenCanvas = g.newCanvas(self.u, self.v)
  146. self:initAnimations()
  147. love.mouse.setCursor(love.mouse.newCursor('media/graphics/cursor' .. ((love.window.getPixelScale() == 2) and '' or '') .. '.png'))
  148. self.gooey:resize()
  149. self.start:resize()
  150. self.choose:resize()
  151. self.campaign:resize()
  152. self.select:resize()
  153. if self.optionsPane then self.optionsPane:resize() end
  154. self.canvas = g.newCanvas(u, v)
  155. self.workingCanvas = g.newCanvas(u, v)
  156. self:refreshBackground()
  157. end
  158. function Menu:startGame(gameOptions)
  159. if not gameOptions or not gameOptions.biome then return end
  160. if self.menuSounds then self.menuSounds:stop() end
  161. Context:remove(ctx)
  162. Context:add(Game, self.user, self.options, gameOptions)
  163. end
  164. function Menu:refreshBackground()
  165. local u, v = self.u, self.v
  166. if not self.background1 or not self.background2 then return end
  167. g.setColor(255, 255, 255)
  168. self.background2:renderTo(function()
  169. g.draw(self.background1)
  170. end)
  171. self.background1:clear(255, 255, 255, 0)
  172. self.workingCanvas:clear(255, 255, 255, 0)
  173. self.background1:renderTo(function()
  174. local image = data.media.graphics.map[self.campaign.biome or 'forest']
  175. g.draw(image, 0, 0, 0, u / image:getWidth(), v / image:getHeight())
  176. end)
  177. data.media.shaders.horizontalBlur:send('amount', .0016)
  178. data.media.shaders.verticalBlur:send('amount', .0016 * u / v)
  179. for i = 1, 3 do
  180. g.setShader(data.media.shaders.horizontalBlur)
  181. self.workingCanvas:renderTo(function()
  182. g.draw(self.background1)
  183. end)
  184. g.setShader(data.media.shaders.verticalBlur)
  185. self.background1:renderTo(function()
  186. g.draw(self.workingCanvas)
  187. end)
  188. end
  189. g.setShader()
  190. self.backgroundAlpha = 0
  191. end
  192. function Menu:drawBackground()
  193. local u, v = self.u, self.v
  194. local backgroundAlpha = lume.lerp(self.prevBackgroundAlpha, self.backgroundAlpha, ls.accum / ls.tickrate)
  195. g.setColor(255, 255, 255)
  196. g.draw(self.background2, 0, 0)
  197. g.setColor(255, 255, 255, backgroundAlpha * 255)
  198. g.draw(self.background1, 0, 0)
  199. g.setColor(0, 0, 0, 50)
  200. g.rectangle('fill', 0, 0, u, v)
  201. end
  202. function Menu:initAnimations()
  203. self.animations = {}
  204. self.animations.muju = data.animation.muju({scale = 1, default = 'resurrect'})
  205. self.animations.muju.flipped = true
  206. self.animations.muju:on('complete', function(data)
  207. self.animations.muju:set('idle', {force = true})
  208. end)
  209. self.animations.muju:on('event', function(data)
  210. if data.data.name == 'flor' then
  211. f.exe(self[self.page].mujuDead, self[self.page])
  212. end
  213. end)
  214. self.animationScales = {
  215. thuju = .55,
  216. bruju = 1.3,
  217. xuju = .55,
  218. kuju = .6
  219. }
  220. self.animationTransforms = {}
  221. self.prevAnimationTransforms = {}
  222. for _, code in pairs(config.starters) do
  223. self.animations[code] = data.animation[code]({scale = self.animationScales[code]})
  224. self.animations[code]:on('complete', function() self.animations[code]:set('idle', {force = true}) end)
  225. self.animationTransforms[code] = {}
  226. self.prevAnimationTransforms[code] = {}
  227. end
  228. end
  229. function Menu:setPage(page, ...)
  230. -- Deactivate the old page
  231. self[self.page].active = false
  232. f.exe(self[self.page].deactivate, self[self.page])
  233. -- Activate the new page
  234. self.page = page
  235. self[self.page].active = true
  236. f.exe(self[self.page].activate, self[self.page], ...)
  237. self:mousemoved(love.mouse.getPosition())
  238. end