diff --git a/includes/LICENSE b/includes/LICENSE index c67ec8d..e96386b 100644 --- a/includes/LICENSE +++ b/includes/LICENSE @@ -3,6 +3,8 @@ RGB is Copyright (c) 2015 Paul Liverman III RGB uses the following libraries: - HUMP Gamestate, Copyright (c) 2010-2013 Matthias Richter +- GameJolt.lua, Copyright (c) 2015 insweater +- inifile, Copyright (c) 2011-2015 Bart van Strien All of these libraries and RGB itself are licensed under the MIT License: diff --git a/icons/Game Jolt thumbnail.png b/logos/Game Jolt thumbnail.png similarity index 100% rename from icons/Game Jolt thumbnail.png rename to logos/Game Jolt thumbnail.png diff --git a/src/game.lua b/src/gamestates/game.lua similarity index 89% rename from src/game.lua rename to src/gamestates/game.lua index a075c5d..0dd76a3 100644 --- a/src/game.lua +++ b/src/gamestates/game.lua @@ -1,8 +1,9 @@ love.math.setRandomSeed(os.time()) -- Gamestates ---local won = require "won" --TODO MAKE THIS -local lost = require "lost" +--local won = require "gamestates.won" --TODO MAKE THIS +local lost = require "gamestates.lost" +local paused = require "gamestates.paused" -- This Gamestate local game = {} @@ -75,9 +76,14 @@ function game:enter(previous, settings) nextLevel() end -function game:resume(previous) - game:enter(previousState) --we want to keep the old values - totalScore = 0 --this should have happened in game:leave() but does not for an unknown reason +function game:resume(previous, action) + if action == "LOST" then + game:enter(previousState) --we want to keep the old values + totalScore = 0 --this should have happened in game:leave() but does not for an unknown reason + end + if action == "UNPAUSED" then + love.graphics.setNewFont(28) -- fix our font! + end end function game:update(dt) @@ -190,9 +196,17 @@ function game:leave() end function game:keypressed(key, unicode) - if key == "escape" then + if key == " " then + Gamestate.push(paused, love.graphics.newScreenshot()) + elseif key == "escape" then Gamestate.switch(previousState) end end +function game:focus(isFocused) + if not isFocused then + Gamestate.push(paused, love.graphics.newScreenshot()) + end +end + return game diff --git a/src/lost.lua b/src/gamestates/lost.lua similarity index 84% rename from src/lost.lua rename to src/gamestates/lost.lua index 54c03e9..48e44b4 100644 --- a/src/lost.lua +++ b/src/gamestates/lost.lua @@ -22,7 +22,7 @@ function lost:draw() love.graphics.setNewFont(50) love.graphics.printf(string.format("Final Score: %.1f", score), 0, love.graphics.getHeight() / 2 - 25, love.graphics.getWidth(), "center") love.graphics.setNewFont(16) - love.graphics.printf("(Click to restart.)", 0, love.graphics.getHeight() * 3/4 - 8, love.graphics.getWidth(), "center") + love.graphics.printf("(Press Esc to restart.)", 0, love.graphics.getHeight() * 3/4 - 8, love.graphics.getWidth(), "center") --[[ love.graphics.printf(string.format("Total Score: %.1f", totalScore), 0, 3, screenWidth / 2, "center") --love.graphics.printf(string.format("Best Score: %.1f", bestScore), screenWidth / 2, 3, screenWidth / 2, "center") @@ -34,11 +34,21 @@ function lost:draw() ]] end +---[[ function lost:mousepressed(x, y, button) if button == "l" then - Gamestate.pop() + Gamestate.pop("LOST") --Gamestate.switch(previousState) end end +--]] + +function lost:keypressed(key, unicode) + if key == " " then + Gamestate.pop("LOST") + elseif key == "escape" then + Gamestate.pop("LOST") + end +end return lost diff --git a/src/menu.lua b/src/gamestates/menu.lua similarity index 96% rename from src/menu.lua rename to src/gamestates/menu.lua index 3d4ae87..61e2720 100644 --- a/src/menu.lua +++ b/src/gamestates/menu.lua @@ -1,5 +1,5 @@ local Gamestate = require "lib.gamestate" -local game = require "game" +local game = require "gamestates.game" local menu = {} @@ -24,7 +24,7 @@ end function menu:mousepressed(x, y, button) if button == "l" then -- TODO replace constructed settings object with actual loaded settings - Gamestate.switch(game, {boxSize = 20, colorStep = 80, timeLimit = 60}) + Gamestate.switch(game, {boxSize = 20, colorStep = 80, timeLimit = 10}) end end diff --git a/src/gamestates/paused.lua b/src/gamestates/paused.lua new file mode 100644 index 0000000..f58c5ad --- /dev/null +++ b/src/gamestates/paused.lua @@ -0,0 +1,41 @@ +local paused = {} + +local previousState, screenshot + +function paused:enter(previous, screenImageData) + previousState = previous + screenshot = love.graphics.newImage(screenImageData) +end + +function paused:draw() + -- draw the screenshot + love.graphics.setColor(255, 255, 255) + love.graphics.draw(screenshot) + -- draw a partial transparency black to fade out the screenshot + love.graphics.setColor(0, 0, 0, 200) + love.graphics.rectangle("fill", 0, 0, love.graphics.getWidth(), love.graphics.getHeight()) + -- print info + love.graphics.setNewFont(40) + love.graphics.setColor(255, 255, 255) + love.graphics.printf("Paused", 0, love.graphics.getHeight() * 2/5 - 20, love.graphics.getWidth(), "center") + love.graphics.setNewFont(20) + love.graphics.printf("(Press Esc to resume.)", 0, love.graphics.getHeight() * 3/5 - 10, love.graphics.getWidth(), "center") +end + +---[[ +function paused:mousepressed(x, y, button) + if button == "l" then + Gamestate.pop("UNPAUSED") + end +end +--]] + +function paused:keypressed(key, unicode) + if key == " " then + Gamestate.pop("UNPAUSED") + elseif key == "escape" then + Gamestate.pop("UNPAUSED") + end +end + +return paused diff --git a/src/lib/inifile.lua b/src/lib/inifile.lua new file mode 100644 index 0000000..cd772cc --- /dev/null +++ b/src/lib/inifile.lua @@ -0,0 +1,182 @@ +local inifile = { + _VERSION = "inifile 1.0", + _DESCRIPTION = "Inifile is a simple, complete ini parser for lua", + _URL = "http://docs.bartbes.com/inifile", + _LICENSE = [[ + Copyright 2011-2015 Bart van Strien. All rights reserved. + + Redistribution and use in source and binary forms, with or without modification, are + permitted provided that the following conditions are met: + + 1. Redistributions of source code must retain the above copyright notice, this list of + conditions and the following disclaimer. + + 2. Redistributions in binary form must reproduce the above copyright notice, this list + of conditions and the following disclaimer in the documentation and/or other materials + provided with the distribution. + + THIS SOFTWARE IS PROVIDED BY BART VAN STRIEN ''AS IS'' AND ANY EXPRESS OR IMPLIED + WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND + FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL BART VAN STRIEN OR + CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR + CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR + SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON + ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING + NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF + ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + The views and conclusions contained in the software and documentation are those of the + authors and should not be interpreted as representing official policies, either expressed + or implied, of Bart van Strien. + ]] -- The above license is known as the Simplified BSD license. +} + +local defaultBackend = "io" + +local backends = { + io = { + lines = function(name) return assert(io.open(name)):lines() end, + write = function(name, contents) assert(io.open(name, "w")):write(contents) end, + }, + memory = { + lines = function(text) return text:gmatch("([^\r\n]+)\r?\n") end, + write = function(name, contents) return contents end, + }, +} + +if love then + backends.love = { + lines = love.filesystem.lines, + write = function(name, contents) love.filesystem.write(name, contents) end, + } + defaultBackend = "love" +end + +function inifile.parse(name, backend) + backend = backend or defaultBackend + local t = {} + local section + local comments = {} + local sectionorder = {} + local cursectionorder + + for line in backends[backend].lines(name) do + + -- Section headers + local s = line:match("^%[([^%]]+)%]$") + if s then + section = s + t[section] = t[section] or {} + cursectionorder = {name = section} + table.insert(sectionorder, cursectionorder) + end + + -- Comments + s = line:match("^;(.+)$") + if s then + local commentsection = section or comments + comments[commentsection] = comments[commentsection] or {} + table.insert(comments[commentsection], s) + end + + -- Key-value pairs + local key, value = line:match("^([%w_]+)%s-=%s-(.+)$") + if tonumber(value) then value = tonumber(value) end + if value == "true" then value = true end + if value == "false" then value = false end + if key and value ~= nil then + t[section][key] = value + table.insert(cursectionorder, key) + end + end + + -- Store our metadata in the __inifile field in the metatable + return setmetatable(t, { + __inifile = { + comments = comments, + sectionorder = sectionorder, + } + }) +end + +function inifile.save(name, t, backend) + backend = backend or defaultBackend + local contents = {} + + -- Get our metadata if it exists + local metadata = getmetatable(t) + local comments, sectionorder + + if metadata then metadata = metadata.__inifile end + if metadata then + comments = metadata.comments + sectionorder = metadata.sectionorder + end + + -- If there are comments before sections, + -- write them out now + if comments and comments[comments] then + for i, v in ipairs(comments[comments]) do + table.insert(contents, (";%s"):format(v)) + end + table.insert(contents, "") + end + + local function writevalue(section, key) + local value = section[key] + -- Discard if it doesn't exist (anymore) + if value == nil then return end + table.insert(contents, ("%s=%s"):format(key, tostring(value))) + end + + local function writesection(section, order) + local s = t[section] + -- Discard if it doesn't exist (anymore) + if not s then return end + table.insert(contents, ("[%s]"):format(section)) + + -- Write our comments out again, sadly we have only achieved + -- section-accuracy so far + if comments and comments[section] then + for i, v in ipairs(comments[section]) do + table.insert(contents, (";%s"):format(v)) + end + end + + -- Write the key-value pairs with optional order + local done = {} + if order then + for _, v in ipairs(order) do + done[v] = true + writevalue(s, v) + end + end + for i, _ in pairs(s) do + if not done[i] then + writevalue(s, i) + end + end + + -- Newline after the section + table.insert(contents, "") + end + + -- Write the sections, with optional order + local done = {} + if sectionorder then + for _, v in ipairs(sectionorder) do + done[v.name] = true + writesection(v.name, v) + end + end + -- Write anything that wasn't ordered + for i, _ in pairs(t) do + if not done[i] then + writesection(i) + end + end + + return backends[backend].write(name, table.concat(contents, "\n")) +end + +return inifile diff --git a/src/main.lua b/src/main.lua index bf3f409..5693de5 100644 --- a/src/main.lua +++ b/src/main.lua @@ -1,14 +1,48 @@ Gamestate = require "lib.gamestate" -Gamejolt = require "gamejolt" +Gamejolt = require "lib.gamejolt" -local menu = require "menu" +local inifile = require "lib.inifile" + +local menu = require "gamestates.menu" function love.load() + -- set custom window icon local icon = love.image.newImageData("icon.png") love.window.setIcon(icon) + -- initialize Game Jolt + Gamejolt.init(48728, "b8e4a0eae1509d3edef3d8451bae1842") + -- load settings and change if needed - --love.window.setMode(800, 460, {borderless = true}) --temporary + if love.filesystem.isFile("settings.ini") then + local settings = inifile.parse("settings.ini") + love.window.setMode(settings.display.width, settings.display.height, {fullscreen = settings.display.fullscreen, borderless = settings.display.borderless}) + -- login if we have the data to do so + if settings.gamejolt.username and settings.gamejolt.usertoken then + local authSuccess = Gamejolt.authUser(settings.gamejolt.username, settings.gamejolt.usertoken) + if authSuccess then + -- check if the player has been banned + local userInfo = Gamejolt.fetchUserByName(settings.gamejolt.username) + if userInfo.status == "Banned" then + settings.gamejolt.username = false + settings.gamejolt.usertoken = false + inifile.save("settings.ini", settings) + error("You have been banned from Game Jolt. Your login data has been deleted, re-open RGB to continue playing without Game Jolt account integration.") + end + local sessionSuccess = Gamejolt.openSession() -- tell Game Jolt the user is playing + if sessionSuccess then + local idleSuccess = Gamejolt.pingSession(false) + if not idleSuccess then + print("Couldn't ping Gamejolt session. Session may close.") --this is lazy but I don't care + end + else + print("Couldn't open a session with Game Jolt.") + end + else + print("Failed to log into Game Jolt. Please report this error (with a screenshot) to: paul.liverman.iii@gmail.com") + end + end + end Gamestate.registerEvents() Gamestate.switch(menu) diff --git a/src/original.lua b/src/original.lua deleted file mode 100644 index d0a6cf4..0000000 --- a/src/original.lua +++ /dev/null @@ -1,62 +0,0 @@ -local game = {} - -local boxes = {} -local boxSize = 20 -local wAmount = math.floor(love.graphics.getWidth() / boxSize) -local hAmount = math.floor(love.graphics.getHeight() / boxSize) - --- initial black boxes -for i=0,wAmount do - boxes[i] = {} - for j=0,hAmount do - boxes[i][j] = {0, 0, 0} - end -end - -function game:draw() - --boxes - for i=0,#boxes do - for j=0,#boxes[i] do - love.graphics.setColor(boxes[i][j]) - love.graphics.rectangle("fill", i * boxSize, j * boxSize, boxSize, boxSize) - end - end - - --lines - love.graphics.setColor(255, 255, 255) - for i=0,wAmount do - love.graphics.line(i * boxSize, 0, i * boxSize, love.graphics.getHeight()) - - end - for j=0,hAmount do - love.graphics.line(0, j * boxSize, love.graphics.getWidth(), j * boxSize) - end -end - -function game:mousepressed(x, y, button) - print(button) --debug - if button == "l" then - boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][1] = boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][1] + 40 - if boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][1] > 255 then - boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][1] = 0 - end - elseif button == "m" or button == "wu" or button == "wd" then - boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][2] = boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][2] + 40 - if boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][2] > 255 then - boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][2] = 0 - end - elseif button == "r" then - boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][3] = boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][3] + 40 - if boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][3] > 255 then - boxes[math.floor(x / boxSize)][math.floor(y / boxSize)][3] = 0 - end - end -end - -function game:keypressed(key, unicode) - if key == "escape" then - love.event.quit() - end -end - -return game