@@ -5,14 +5,7 @@ local thrusterMax = 0 | |||||
local animationComplete = false | local animationComplete = false | ||||
local frame = 0 | local frame = 0 | ||||
asteroidImage = love.graphics.newImage("entities/planet/asteroid.png") | asteroidImage = love.graphics.newImage("entities/planet/asteroid.png") | ||||
function love.keyreleased(key) | |||||
if key == "escape" and gameStatus == "play" then | |||||
if pauseStatus then | |||||
pauseStatus = false | |||||
else pauseStatus = true | |||||
end | |||||
end | |||||
end | |||||
function levelgeneral.update(dt) | function levelgeneral.update(dt) | ||||
if not pauseStatus then | if not pauseStatus then | ||||
if not levelLoaded then | if not levelLoaded then | ||||
@@ -72,6 +65,8 @@ else | |||||
camera:follow(VCAM.x, VCAM.y) | camera:follow(VCAM.x, VCAM.y) | ||||
end | end | ||||
levelgeneral.GUIControl() | levelgeneral.GUIControl() | ||||
else | |||||
settingsMenuUpdate(dt) | |||||
end | end | ||||
end | end | ||||
@@ -127,7 +122,7 @@ function levelgeneral.draw() | |||||
end | end | ||||
if gameStatus == "setup" and not reachedGoal then | if gameStatus == "setup" and not reachedGoal then | ||||
level.hint() | level.hint() | ||||
elseif gameStatus == "play" then | |||||
elseif gameStatus == "play" and not pauseStatus then | |||||
if not reachedGoal then | if not reachedGoal then | ||||
love.graphics.printf("[W] Thrusters: ", 0, WINDOW_HEIGHT-100, 300, "center") | love.graphics.printf("[W] Thrusters: ", 0, WINDOW_HEIGHT-100, 300, "center") | ||||
local m = smallfont:getWidth("[W] Thrusters: ") | local m = smallfont:getWidth("[W] Thrusters: ") | ||||
@@ -1,8 +1,10 @@ | |||||
menu = Class{} | menu = Class{} | ||||
menuMode = "main" | |||||
local M = {} | local M = {} | ||||
menuLoaded = false | menuLoaded = false | ||||
function menu.update(dt) | function menu.update(dt) | ||||
if not menuLoaded then | if not menuLoaded then | ||||
firstShip.x = -100 | firstShip.x = -100 | ||||
menuLoaded = true | menuLoaded = true | ||||
planets = {} | planets = {} | ||||
@@ -31,6 +33,15 @@ function menu.update(dt) | |||||
end | end | ||||
--print("ship is hit") | --print("ship is hit") | ||||
end | end | ||||
if menuMode == "settings" then | |||||
local mx, my = love.mouse.getPosition() | |||||
local vmx, vmy = camera:getMousePosition() | |||||
local vmx = vmx * DIFFERENCE_X | |||||
local vmy = vmy * DIFFERENCE_Y | |||||
local mx = mx * DIFFERENCE_X | |||||
local my = my * DIFFERENCE_Y | |||||
volumeSlider:update(mx, my) | |||||
end | |||||
end | end | ||||
function menu.draw(dt) | function menu.draw(dt) | ||||
@@ -44,7 +55,19 @@ function menu.draw(dt) | |||||
else | else | ||||
love.graphics.setFont(titlefont) | love.graphics.setFont(titlefont) | ||||
love.graphics.printf("NuclearGravity", 0, 20, WINDOW_WIDTH, "center") | love.graphics.printf("NuclearGravity", 0, 20, WINDOW_WIDTH, "center") | ||||
if menuMode == "main" then | |||||
menu:butt(buttons, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 40, WINDOW_WIDTH/3) | menu:butt(buttons, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 40, WINDOW_WIDTH/3) | ||||
elseif menuMode == "settings" then | |||||
menu:butt(mainsettings, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 40, WINDOW_WIDTH/3) | |||||
love.graphics.setColor(254, 67, 101) | |||||
love.graphics.setFont(tinyfont) | |||||
love.graphics.printf("Sound volume:", 0, WINDOW_HEIGHT/2-140, WINDOW_WIDTH, "center") | |||||
-- draw slider, set color and line style before calling | |||||
volumeSlider:draw() | |||||
else | |||||
print("[EE]No menu found! " .. menu.mode) | |||||
end | |||||
love.keyboard.mouseisReleased = false | love.keyboard.mouseisReleased = false | ||||
end | end | ||||
end | end | ||||
@@ -4,6 +4,7 @@ local M = {} | |||||
local currenctScore = 0 | local currenctScore = 0 | ||||
function practice.update(dt) | function practice.update(dt) | ||||
if not pauseStatus then | |||||
if not levelLoaded then | if not levelLoaded then | ||||
shipsleft = 1 | shipsleft = 1 | ||||
planetsleft = 10 | planetsleft = 10 | ||||
@@ -38,6 +39,7 @@ function practice.update(dt) | |||||
levelLoaded = true | levelLoaded = true | ||||
end | end | ||||
camera:update(dt) | camera:update(dt) | ||||
--print(camera.x .. " " .. camera.y) | --print(camera.x .. " " .. camera.y) | ||||
for i, explosion in ipairs(explosions) do | for i, explosion in ipairs(explosions) do | ||||
explosion:update(dt) | explosion:update(dt) | ||||
@@ -63,7 +65,7 @@ function practice.update(dt) | |||||
planets[i]:update(dt) | planets[i]:update(dt) | ||||
if math.sqrt((firstShip.x - planets[i].x)^2 + (firstShip.y - planets[i].y)^2) > planets[i].w/3 then | if math.sqrt((firstShip.x - planets[i].x)^2 + (firstShip.y - planets[i].y)^2) > planets[i].w/3 then | ||||
currentScore = currentScore + math.sqrt(planets[i].attractionX^2 + planets[i].attractionY^2)*100 | currentScore = currentScore + math.sqrt(planets[i].attractionX^2 + planets[i].attractionY^2)*100 | ||||
print(math.sqrt(planets[i].attractionX^2 + planets[i].attractionY^2)) | |||||
--print(math.sqrt(planets[i].attractionX^2 + planets[i].attractionY^2)) | |||||
end | end | ||||
end | end | ||||
for i in ipairs(cannons) do | for i in ipairs(cannons) do | ||||
@@ -83,8 +85,9 @@ else | |||||
camera:follow(VCAM.x, VCAM.y) | camera:follow(VCAM.x, VCAM.y) | ||||
end | end | ||||
practice.GUIControl() | practice.GUIControl() | ||||
else | |||||
settingsMenuUpdate(dt) | |||||
end | |||||
end | end | ||||
function practice.draw() | function practice.draw() | ||||
@@ -118,15 +121,17 @@ function practice.draw() | |||||
local textW = tinyfont:getWidth("Top score: " .. math.floor(saveData.score/100)) | local textW = tinyfont:getWidth("Top score: " .. math.floor(saveData.score/100)) | ||||
love.graphics.print("Top score: " .. math.floor(saveData.score/100), WINDOW_WIDTH/2-textW/2, 10) | love.graphics.print("Top score: " .. math.floor(saveData.score/100), WINDOW_WIDTH/2-textW/2, 10) | ||||
practice.hint() | practice.hint() | ||||
elseif gameStatus == "play" then | |||||
elseif gameStatus == "play" and not pauseStatus then | |||||
local textW = tinyfont:getWidth("Score: " .. math.floor(currentScore/100)) | local textW = tinyfont:getWidth("Score: " .. math.floor(currentScore/100)) | ||||
love.graphics.setFont(tinyfont) | love.graphics.setFont(tinyfont) | ||||
love.graphics.print("Score: " .. math.floor(currentScore/100), WINDOW_WIDTH/2-textW/2, 10) | love.graphics.print("Score: " .. math.floor(currentScore/100), WINDOW_WIDTH/2-textW/2, 10) | ||||
guimenu:butt(playbutts, WINDOW_WIDTH, WINDOW_HEIGHT, 1100, WINDOW_HEIGHT-50, 40, WINDOW_WIDTH/3) | guimenu:butt(playbutts, WINDOW_WIDTH, WINDOW_HEIGHT, 1100, WINDOW_HEIGHT-50, 40, WINDOW_WIDTH/3) | ||||
love.keyboard.mouseisReleased = false | |||||
end | end | ||||
if pauseStatus then | |||||
drawPauseMenu() | |||||
love.keyboard.mouseisReleased = false | |||||
end | |||||
end | end | ||||
@@ -142,6 +147,9 @@ function practice.reset() | |||||
firstShip:reset() | firstShip:reset() | ||||
camera.scale = 1 | camera.scale = 1 | ||||
projectiles = {} | projectiles = {} | ||||
for i in ipairs(cannons) do | |||||
cannons[i].timer = cannons[i].otimer | |||||
end | |||||
shipsleft = 1 | shipsleft = 1 | ||||
if currentScore > saveData.score then | if currentScore > saveData.score then | ||||
@@ -18,7 +18,7 @@ saveData = { | |||||
levelsBeaten = 0, | levelsBeaten = 0, | ||||
score = 0 | score = 0 | ||||
} | } | ||||
mainsettings = {} | |||||
planets = {} | planets = {} | ||||
buttons = {} | buttons = {} | ||||
cannons = {} | cannons = {} | ||||
@@ -33,7 +33,17 @@ function love.wheelmoved(x, y) | |||||
end | end | ||||
end | end | ||||
end | end | ||||
function love.keyreleased(key) | |||||
if key == "escape" and gameStatus == "play" then | |||||
if pauseStatus then | |||||
pauseStatus = false | |||||
pauseState = "main" | |||||
else pauseStatus = true | |||||
end | |||||
end | |||||
end | |||||
function love.load() | function love.load() | ||||
love.graphics.setLineWidth(4) | |||||
print(love.filesystem.getAppdataDirectory()) | print(love.filesystem.getAppdataDirectory()) | ||||
print(love.filesystem.getSaveDirectory()) | print(love.filesystem.getSaveDirectory()) | ||||
print(love.filesystem.areSymlinksEnabled()) | print(love.filesystem.areSymlinksEnabled()) | ||||
@@ -24,8 +24,10 @@ If you're on arch, install the prerequisites with: | |||||
`` | `` | ||||
Changelog: | |||||
Changelog history: | |||||
- Changed practice scoring system | - Changed practice scoring system | ||||
- Fixed bug with cannon timers not resetting | - Fixed bug with cannon timers not resetting | ||||
- Toggle music button added | - Toggle music button added | ||||
- Added the pause menu | - Added the pause menu | ||||
- Volume slider added | |||||
- Made trail **wider** |
@@ -9,7 +9,7 @@ function buttonClutter() | |||||
function() | function() | ||||
gameState = "selectlv" | gameState = "selectlv" | ||||
end)) | end)) | ||||
table.insert(buttons, menu:addButton("Toggle Fullscreen", | |||||
table.insert(mainsettings, menu:addButton("Toggle Fullscreen", | |||||
function() | function() | ||||
myscreen:toggle(WINDOW_HEIGHT, WINDOW_WIDTH) | myscreen:toggle(WINDOW_HEIGHT, WINDOW_WIDTH) | ||||
DIFFERENCE_X = myscreen.c | DIFFERENCE_X = myscreen.c | ||||
@@ -17,9 +17,13 @@ function buttonClutter() | |||||
OFFSET_X = myscreen.e | OFFSET_X = myscreen.e | ||||
OFFSET_Y = myscreen.f | OFFSET_Y = myscreen.f | ||||
end)) | end)) | ||||
table.insert(buttons, menu:addButton("Toggle Music", | |||||
table.insert(mainsettings, menu:addButton("back", | |||||
function() | |||||
menuMode = "main" | |||||
end)) | |||||
table.insert(buttons, menu:addButton("Settings", | |||||
function() | function() | ||||
toggleMusic() | |||||
menuMode = "settings" | |||||
end | end | ||||
)) | )) | ||||
@@ -8,6 +8,7 @@ require 'entities/planet/planet' | |||||
require 'src/buttonClutter' | require 'src/buttonClutter' | ||||
require 'entities/explosion/explosion' | require 'entities/explosion/explosion' | ||||
require 'src/GUI' | require 'src/GUI' | ||||
require 'src/simple-slider' | |||||
require 'src/pauseMenu' | require 'src/pauseMenu' | ||||
require 'src/stateMachine' | require 'src/stateMachine' | ||||
require 'entities/base/base' | require 'entities/base/base' | ||||
@@ -1,6 +1,9 @@ | |||||
pauseStatus = false | pauseStatus = false | ||||
pauseState = "main" | |||||
pauseMenu = {} | pauseMenu = {} | ||||
settings = {} | |||||
function pauseMake() | function pauseMake() | ||||
volumeSlider = newSlider(WINDOW_WIDTH/2, WINDOW_HEIGHT/2-100, 300, 0.5, 0, 1, function (v) love.audio.setVolume(v) end) | |||||
table.insert(pauseMenu, menu:addButton("Resume", | table.insert(pauseMenu, menu:addButton("Resume", | ||||
function() | function() | ||||
pauseStatus = false | pauseStatus = false | ||||
@@ -12,7 +15,7 @@ function() | |||||
goBack() | goBack() | ||||
end | end | ||||
)) | )) | ||||
table.insert(pauseMenu, menu:addButton("Toggle Fullscreen", | |||||
table.insert(settings, menu:addButton("Toggle Fullscreen", | |||||
function() | function() | ||||
myscreen:toggle(WINDOW_HEIGHT, WINDOW_WIDTH) | myscreen:toggle(WINDOW_HEIGHT, WINDOW_WIDTH) | ||||
DIFFERENCE_X = myscreen.c | DIFFERENCE_X = myscreen.c | ||||
@@ -21,9 +24,14 @@ function() | |||||
OFFSET_Y = myscreen.f | OFFSET_Y = myscreen.f | ||||
end | end | ||||
)) | )) | ||||
table.insert(pauseMenu, menu:addButton("Toggle Music", | |||||
table.insert(settings, menu:addButton("back", | |||||
function() | function() | ||||
toggleMusic() | |||||
pauseState = "main" | |||||
end | |||||
)) | |||||
table.insert(pauseMenu, menu:addButton("Settings", | |||||
function() | |||||
pauseState = "settings" | |||||
end | end | ||||
)) | )) | ||||
table.insert(pauseMenu, menu:addButton("Quit", | table.insert(pauseMenu, menu:addButton("Quit", | ||||
@@ -34,5 +42,30 @@ end | |||||
end | end | ||||
function drawPauseMenu() | function drawPauseMenu() | ||||
-- print("draw") | -- print("draw") | ||||
if pauseState == "main" then | |||||
menu:butt(pauseMenu, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 40, WINDOW_WIDTH/3) | menu:butt(pauseMenu, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 40, WINDOW_WIDTH/3) | ||||
end | |||||
end | |||||
if pauseState == "settings" then | |||||
menu:butt(settings, WINDOW_WIDTH, WINDOW_HEIGHT, WINDOW_WIDTH/2, WINDOW_HEIGHT/2, 40, WINDOW_WIDTH/3) | |||||
love.graphics.setLineWidth(4) | |||||
love.graphics.setColor(254, 67, 101) | |||||
love.graphics.setFont(tinyfont) | |||||
love.graphics.printf("Sound volume:", 0, WINDOW_HEIGHT/2-140, WINDOW_WIDTH, "center") | |||||
-- draw slider, set color and line style before calling | |||||
volumeSlider:draw() | |||||
end | |||||
end | |||||
function settingsMenuUpdate(dt) | |||||
if pauseState == "settings" then | |||||
local mx, my = love.mouse.getPosition() | |||||
local vmx, vmy = camera:getMousePosition() | |||||
local vmx = vmx * DIFFERENCE_X | |||||
local vmy = vmy * DIFFERENCE_Y | |||||
local mx = mx * DIFFERENCE_X | |||||
local my = my * DIFFERENCE_Y | |||||
volumeSlider:update(mx, my) | |||||
-- print("updating") | |||||
end | |||||
-- print("called?") | |||||
end |
@@ -0,0 +1,138 @@ | |||||
--[[ | |||||
Copyright (c) 2016 George Prosser | |||||
Permission is hereby granted, free of charge, to any person | |||||
obtaining a copy of this software and associated documentation | |||||
files (the "Software"), to deal in the Software without | |||||
restriction, including without limitation the rights to use, | |||||
copy, modify, merge, publish, distribute, sublicense, and/or sell | |||||
copies of the Software, and to permit persons to whom the | |||||
Software is furnished to do so, subject to the following | |||||
conditions: | |||||
The above copyright notice and this permission notice shall be | |||||
included in all copies or substantial portions of the Software. | |||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, | |||||
EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES | |||||
OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND | |||||
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT | |||||
HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, | |||||
WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING | |||||
FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR | |||||
OTHER DEALINGS IN THE SOFTWARE. | |||||
]] | |||||
local slider = {} | |||||
slider.__index = slider | |||||
function newSlider(x, y, length, value, min, max, setter, style) | |||||
local s = {} | |||||
s.value = (value - min) / (max - min) | |||||
s.min = min | |||||
s.max = max | |||||
s.setter = setter | |||||
s.x = x | |||||
s.y = y | |||||
s.length = length | |||||
local p = style or {} | |||||
s.width = p.width or length * 0.1 | |||||
s.orientation = p.orientation or 'horizontal' | |||||
s.track = p.track or 'rectangle' | |||||
s.knob = p.knob or 'rectangle' | |||||
s.grabbed = false | |||||
s.wasDown = true | |||||
s.ox = 0 | |||||
s.oy = 0 | |||||
return setmetatable(s, slider) | |||||
end | |||||
function slider:update(mouseX, mouseY, mouseDown) | |||||
local x = mouseX or love.mouse.getX() | |||||
local y = mouseY or love.mouse.getY() | |||||
local down = love.mouse.isDown(1) | |||||
if mouseDown ~= nil then | |||||
down = mouseDown | |||||
end | |||||
local knobX = self.x | |||||
local knobY = self.y | |||||
if self.orientation == 'horizontal' then | |||||
knobX = self.x - self.length/2 + self.length * self.value | |||||
elseif self.orientation == 'vertical' then | |||||
knobY = self.y + self.length/2 - self.length * self.value | |||||
end | |||||
local ox = x - knobX | |||||
local oy = y - knobY | |||||
local dx = ox - self.ox | |||||
local dy = oy - self.oy | |||||
if down then | |||||
if self.grabbed then | |||||
if self.orientation == 'horizontal' then | |||||
self.value = self.value + dx / self.length | |||||
elseif self.orientation == 'vertical' then | |||||
self.value = self.value - dy / self.length | |||||
end | |||||
elseif (x > knobX - self.width/2 and x < knobX + self.width/2 and y > knobY - self.width/2 and y < knobY + self.width/2) and not self.wasDown then | |||||
self.ox = ox | |||||
self.oy = oy | |||||
self.grabbed = true | |||||
end | |||||
else | |||||
self.grabbed = false | |||||
end | |||||
self.value = math.max(0, math.min(1, self.value)) | |||||
if self.setter ~= nil then | |||||
self.setter(self.min + self.value * (self.max - self.min)) | |||||
end | |||||
self.wasDown = down | |||||
end | |||||
function slider:draw() | |||||
if self.track == 'rectangle' then | |||||
if self.orientation == 'horizontal' then | |||||
love.graphics.rectangle('line', self.x - self.length/2 - self.width/2, self.y - self.width/2, self.length + self.width, self.width) | |||||
elseif self.orientation == 'vertical' then | |||||
love.graphics.rectangle('line', self.x - self.width/2, self.y - self.length/2 - self.width/2, self.width, self.length + self.width) | |||||
end | |||||
elseif self.track == 'line' then | |||||
if self.orientation == 'horizontal' then | |||||
love.graphics.line(self.x - self.length/2, self.y, self.x + self.length/2, self.y) | |||||
elseif self.orientation == 'vertical' then | |||||
love.graphics.line(self.x, self.y - self.length/2, self.x, self.y + self.length/2) | |||||
end | |||||
elseif self.track == 'roundrect' then | |||||
if self.orientation == 'horizontal' then | |||||
love.graphics.rectangle('line', self.x - self.length/2 - self.width/2, self.y - self.width/2, self.length + self.width, self.width, self.width/2, self.width) | |||||
elseif self.orientation == 'vertical' then | |||||
love.graphics.rectangle('line', self.x - self.width/2, self.y - self.length/2 - self.width/2, self.width, self.length + self.width, self.width, self.width/2) | |||||
end | |||||
end | |||||
local knobX = self.x | |||||
local knobY = self.y | |||||
if self.orientation == 'horizontal' then | |||||
knobX = self.x - self.length/2 + self.length * self.value | |||||
elseif self.orientation == 'vertical' then | |||||
knobY = self.y + self.length/2 - self.length * self.value | |||||
end | |||||
if self.knob == 'rectangle' then | |||||
love.graphics.rectangle('fill', knobX - self.width/2, knobY - self.width/2, self.width, self.width) | |||||
elseif self.knob == 'circle' then | |||||
love.graphics.circle('fill', knobX, knobY, self.width/2) | |||||
end | |||||
end | |||||
function slider:getValue() | |||||
return self.min + self.value * (self.max - self.min) | |||||
end |