Commit 91245741 authored by babyjeans's avatar babyjeans

Moved to git.rou.sr

parents
.DS_Store
\ No newline at end of file
MIT License
Copyright (c) 2016 babyjeans
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.
# PressPlay
PressPlay was intended to be a 2D Strategy / Simulation game written for [löve2d][love2d] in Lua. It was my intended [Ludum Dare 36][ld36] submission, but I didn't finish it on time which is pretty par for the course.
Since the theme of [LD36][ld36] was _Ancient Technology_ I had decided that VCRs were ancient enough for me, and set out to make a game that was similar to [Papers, Please][pp] but in a light-hearted, "I'm fixing VCRs" way. This is how far I got, not quite all the way there. Like [brewwitch] I hope that this is of use as a learning tool or something, to someone. So here's some code to read!
![PressPlay-Demo](http://babyjeans.grogshack.com/wp-content/uploads/2016/11/ld36-press-play-github-demo.gif)
## Credit
### Things used
* [löve2d][love2d]
* [30log](https://github.com/Yonaba/30log)
* [tween.lua](https://github.com/kikito/tween.lua)
* [04b-03](http://www.dafont.com/04b-03.font)
* [VCR OSD MONO](http://www.dafont.com/vcr-osd-mono.font)
Assets made with [aseprite](http://www.aseprite.org)
[love2d]: https://love2d.org/
[ld36]: http://ludumdare.com/compo/ludum-dare-36/?action=preview
[pp]: http://papersplea.se/
\ No newline at end of file
This diff is collapsed.
function love.conf(t)
t.identity = nil -- The name of the save directory (string)
t.version = "0.10.1" -- The LÖVE version this game was made for (string)
t.console = true -- Attach a console (boolean, Windows only)
t.accelerometerjoystick = true -- Enable the accelerometer on iOS and Android by exposing it as a Joystick (boolean)
t.externalstorage = false -- True to save files (and read from the save directory) in external storage on Android (boolean)
t.gammacorrect = false -- Enable gamma-correct rendering, when supported by the system (boolean)
t.window.title = "Press Play" -- The window title (string)
t.window.icon = nil -- Filepath to an image to use as the window's icon (string)
t.window.width = 960 -- The window width (number)
t.window.height = 540 -- The window height (number)
t.window.borderless = false -- Remove all border visuals from the window (boolean)
t.window.resizable = false -- Let the window be user-resizable (boolean)
t.window.minwidth = 1 -- Minimum window width if the window is resizable (number)
t.window.minheight = 1 -- Minimum window height if the window is resizable (number)
t.window.fullscreen = false -- Enable fullscreen (boolean)
t.window.fullscreentype = "desktop" -- Choose between "desktop" fullscreen or "exclusive" fullscreen mode (string)
t.window.vsync = true -- Enable vertical sync (boolean)
t.window.msaa = 0 -- The number of samples to use with multi-sampled antialiasing (number)
t.window.display = 1 -- Index of the monitor to show the window in (number)
t.window.highdpi = false -- Enable high-dpi mode for the window on a Retina display (boolean)
t.window.x = 30 -- The x-coordinate of the window's position in the specified display (number)
t.window.y = 45 -- The y-coordinate of the window's position in the specified display (number)
t.modules.audio = true -- Enable the audio module (boolean)
t.modules.event = true -- Enable the event module (boolean)
t.modules.graphics = true -- Enable the graphics module (boolean)
t.modules.image = true -- Enable the image module (boolean)
t.modules.joystick = true -- Enable the joystick module (boolean)
t.modules.keyboard = true -- Enable the keyboard module (boolean)
t.modules.math = true -- Enable the math module (boolean)
t.modules.mouse = true -- Enable the mouse module (boolean)
t.modules.physics = true -- Enable the physics module (boolean)
t.modules.sound = true -- Enable the sound module (boolean)
t.modules.system = true -- Enable the system module (boolean)
t.modules.timer = true -- Enable the timer module (boolean), Disabling it will result 0 delta time in love.update
t.modules.touch = true -- Enable the touch module (boolean)
t.modules.video = true -- Enable the video module (boolean)
t.modules.window = true -- Enable the window module (boolean)
t.modules.thread = true -- Enable the thread module (boolean)
end
\ No newline at end of file
-- https://github.com/Yonaba/30log
local assert = assert
local pairs = pairs
local type = type
local tostring = tostring
local setmetatable = setmetatable
local _class
local baseMt = {}
local _instances = setmetatable({},{__mode='k'})
local _classes = setmetatable({},{__mode='k'})
local function assert_class(class, method)
assert(_classes[class], ('Wrong method call. Expected class:%s.'):format(method))
end
local function deep_copy(t, dest, aType)
t = t or {}; local r = dest or {}
for k,v in pairs(t) do
if aType~=nil and type(v)==aType then
r[k] = type(v) == 'table' and deep_copy(v) or v
elseif aType==nil then
r[k] = type(v) == 'table' and k~= '__index' and deep_copy(v) or v
end
end
return r
end
local function instantiate(self,...)
assert_class(self, 'new(...) or class(...)')
local instance = {class = self}
_instances[instance] = tostring(instance)
deep_copy(self, instance, 'table')
instance.mixins = nil
setmetatable(instance,self)
if self.init then
if type(self.init) == 'table' then
deep_copy(self.init, instance)
else
self.init(instance, ...)
end
end
return instance
end
local function extend(self, name, extra_params)
assert_class(self, 'extend(...)')
local heir = {}
_classes[heir] = tostring(heir)
deep_copy(extra_params, deep_copy(self, heir))
heir.name = extra_params and extra_params.name or name
heir.__index = heir
heir.super = self
return setmetatable(heir,self)
end
baseMt = {
__call = function (self,...)
return self:new(...)
end,
__tostring = function(self,...)
if _instances[self] then
return ("instance of '%s' (%s)")
:format(rawget(self.class,'name') or '?', _instances[self])
end
return _classes[self] and ("class '%s' (%s)")
:format(rawget(self,'name') or '?',_classes[self]) or self
end
}
_classes[baseMt] = tostring(baseMt)
setmetatable(baseMt, {__tostring = baseMt.__tostring})
local class = {
isClass = function(class, ofsuper)
local isclass = not not _classes[class]
if ofsuper then
return isclass and (class.super == ofsuper)
end
return isclass
end,
isInstance = function(instance, ofclass)
local isinstance = not not _instances[instance]
if ofclass then
return isinstance and (instance.class == ofclass)
end
return isinstance
end
}
_class = function(name, attr)
local c = deep_copy(attr)
c.mixins = setmetatable({},{__mode='k'})
_classes[c] = tostring(c)
c.name = name or c.name
c.__tostring = baseMt.__tostring
c.__call = baseMt.__call
c.include = function(self,mixin)
assert_class(self, 'include(mixin)')
self.mixins[mixin] = true
return deep_copy(mixin, self, 'function')
end
c.new = instantiate
c.extend = extend
c.__index = c
c.includes = function(self,mixin)
assert_class(self,'includes(mixin)')
return not not (self.mixins[mixin] or (self.super and self.super:includes(mixin)))
end
c.extends = function(self, class)
assert_class(self, 'extends(class)')
local super = self
repeat
super = super.super
until (super == class or super == nil)
return class and (super == class)
end
return setmetatable(c, baseMt)
end
class._DESCRIPTION = '30 lines library for object orientation in Lua'
class._VERSION = '30log v1.0.0'
class._URL = 'http://github.com/Yonaba/30log'
class._LICENSE = 'MIT LICENSE <http://www.opensource.org/licenses/mit-license.php>'
return setmetatable(class,{__call = function(_,...) return _class(...) end })
\ No newline at end of file
This diff is collapsed.
-- pressplay
-- a game wonderfully created by babyjeans
--
-- 3rdparty fonts used:
-- http://www.dafont.com/vcr-osd-mono.font
-- http://www.dafont.com/04b-03.font -- seriously, who doesnt
-- 3rd party library:
-- https://github.com/Yonaba/30log
--
---
-- TODO
-- * Snap Components into ports when installing
-- * Do not allow components to collide
-- * Core Gameplay
-- * Receive VCR with issue
-- * Repair issue
-- * Reward / Loop back
-- * Tools
-- * Screwdriver
-- * Parts Drawer
-- * Board Components as individual sprites
-- * More screws. Screw everything
--
-- POST-LD36 Wishlist:
-- * SpriteBatching
--
---
-- core
class = require('ext/30log-clean')
baby = require('script/baby/baby')
-- types
vector = require('script/util/vector')
Vector2 = require('script/util/vector2')
Rectangle = require('script/util/rectangle')
Circle = require('script/util/circle')
TypingText = require('script/util/typingtext')
GameState = require('script/app/gamestate')
-- global systems
Timers = { }
Draggy = { }
ClickGuy = { }
Resources = { }
-- external types
Tween = require('ext/tween')
-- game specific
require('assets/gamedata')
-- app definition
app = { }
---
-- love2d callbacks
function love.load()
local App = require('script/app/app')
Resources = require('script/app/resources')
initGameData()
app = App()
Timers = require('script/util/timers')
ClickGuy = require('script/util/clickguy')
Tweens = require('script/util/tweens')
app:addState('mainMenu', require('script/game/mainmenu'))
app:addState('game', require('script/game/game'))
app:setState('mainMenu')
end
function love.update()
app:update()
end
function love.draw()
app:draw()
end
function love.keyreleased(key, scancode)
app:keyReleased(key)
end
function love.keypressed(key, scancode, isrepeat)
app:keyPressed(key)
end
\ No newline at end of file
-- app.lua
-- babyjeans
--
-- convenience class for handling app stuff, keeping it out of love namespace
--
---
local App = class("App")
function App:init()
self.states = { }
self.updateHooks = vector()
self.currentState = GameState()
love.graphics.setDefaultFilter('nearest', 'nearest')
love.mouse.setGrabbed(true)
end
function App:addState(name, state)
self.states[name] = state
end
function App:hookUpdate( updateHook )
self.updateHooks:addUnique(updateHook)
end
function App:setState(state)
state = self.states[state]
if state == self.currentState then
return
end
if self.currentState then
self.currentState:exit()
end
self.currentState = state
if self.currentState then
self.currentState:enter()
end
end
function App:draw()
self.currentState:draw()
end
function App:update()
self.currentState:update()
for i, updateHook in ipairs(self.updateHooks.contents) do
updateHook[2](updateHook[1])
end
end
function App:keyReleased(key)
if key == 'escape' then
love.event.quit()
end
self.currentState:onKeyReleased(key)
end
function App:keyPressed(key)
self.currentState:onKeyPressed(key)
end
return App
\ No newline at end of file
-- gamestate.lua
-- gamestate base class
--
---
local GameState = class("GameState")
function GameState:init() end
function GameState:update() end
function GameState:draw() end
function GameState:enter() end
function GameState:exit() end
function GameState:onKeyPressed() end
function GameState:onKeyReleased() end
return GameState
\ No newline at end of file
-- resources.lua
-- babyjeans
--
-- a wrapper / manager of sorts to keep shit.
--
---
local loadedStages = { }
resources = { }
function resources.loadStage(stage)
resources[stage] = { }
for key, resource in pairs(ResourceList[stage]) do
if resource[1] == 'font' then
resources[stage][key] = love.graphics.newFont(resource[2], resource[3])
elseif resource[1] == 'image' then
resources[stage][key] = love.graphics.newImage(resource[2])
end
end
loadedStages[#loadedStages + 1] = stage
end
function resources.unloadStage(stage)
for i, stageName in ipairs(loadedStages) do
if stageName == stage then
table.remove(loadedStages, i)
resources[stage] = { } -- anything with a reference to resources still has them at this point though
return
end
end
end
return resources
\ No newline at end of file
-- baby
-- babyjeans
--
-- the inevitable lua 'engine'
---
-- should name it 'project killer'
---
local baby = class('baby')
babyDebug = require('script/baby/babydebug')
babyGfx = require('script/baby/babygfx')
function baby:init()
end
return baby()
\ No newline at end of file
-- babyDebug
-- babyjeans
--
-- logging / asserting
---
local babyDebug = class('babyDebug')
function babyDebug:err(systemName, errorMsg)
print(systemName .. ' - ' .. errorMsg)
end
function babyDebug:log(systemName, log)
print(systemName .. ' - ' .. log)
end
function babyDebug:warn(systemName, warning)
print(systemName .. ' - ' .. warning)
end
function babyDebug:assert(condition, systemname, errorMsg)
if condition then
return true
end
babyDebug:err(systemname, errorMsg)
end
return babyDebug()
\ No newline at end of file
-- babygfx
-- babyjeans
--
---
local babyGfx = class('babyGfx')
function babyGfx:setColor(r, g, b, a)
if type(r) == 'table' then
if r.r ~= nil then
g=r.g
b=r.b
a=r.a or 255
r=r.r
elseif #r >= 3 then
g=r[2]
b=r[3]
a=r[4] or 255
r=r[1]
else
babyDebug:err('babyGfx:setColor', 'bad params: expect r,g,b,a or \
{ r=r,g=g,b=b,a=a } or { r,g,b,a }');
end
end
--
love.graphics.setColor(r, g, b, a)
end
function babyGfx:pushBlendMode(newBlendMode)
if not babyDebug:assert(type(newBlendMode) == "string", "babyGfx:pushBlendMode", "expected blendModeName") then
return
end
self.blendStack = self.blendStack or { }
local blendMode = love.graphics.getBlendMode() or 'alphamultiplied'
--
love.graphics.setBlendMode('alpha', 'alphamultiply')
end
function babyGfx:popBlendMode()
local num = #self.blendStack
if num == 0 then
return
end
local blendMode = self.blendStack[num]
self.blendStack[num] = nil
--
love.graphics.setBlendMode('alpha', blendMode)
end
return babyGfx()
\ No newline at end of file
-- containerbuilder.lua
-- babyjeans
--
---
local ContainerBuilder = class("ContainerBuilder")
function ContainerBuilder:init()
self.area = Rectangle()
end
function ContainerBuilder:setResources(...)
return self
end
function ContainerBuilder:setArea(x, y, w, h)
self.area = Rectangle(x, y, w, h)
return self
end
return ContainerBuilder
\ No newline at end of file
-- toolbuilder.lua
-- babyjeans
--
---
local ToolBuilder = class('ToolBuilder')
function ToolBuilder:init()
end
function ToolBuilder:setResources(...)
return self
end
function ToolBuilder:onTool()
return self
end
function ToolBuilder:onAltTool()
return self
end
return ToolBuilder
\ No newline at end of file
-- vcrbuilder.lua
-- babyjeans
--
---
local VCRBuilder = class("VCRBuilder")
--
---
function VCRBuilder:init(vcrName, closed, flipped, open, lip, shadows)
self.sections = { }
self.vcrName = vcrName
self.closed = closed
self.flipped = flipped
self.open = open
self.lip = lip
self.shadows = shadows
self.currentSection = nil
self.currentLayer = nil
self.layerIndex = 1
end
function VCRBuilder:Begin(sectionName)
self.currentSection = nil
self.currentLayer = nil
if self.sections[sectionName] then
self.currentSection = sectionName
end
if self.currentSection == nil then
self.currentSection = vector()
end
if self.currentSection:empty() then
self.currentSection:add(vector())
end
self.sections[sectionName] = self.currentSection
self.currentLayer = self.currentSection.contents[1]
self.layerIndex = 1
return self
end
function VCRBuilder:Layer(num)
while self.currentSection:count() < num do
self.currentSection:add(vector())
end
self.currentLayer = self.currentSection.contents[num]
self.layerIndex = num
return self
end
function VCRBuilder:NextLayer()
return self:Layer(self.layerIndex + 1)
end
function VCRBuilder:addComponent(componentBuilder, x, y, connection)
if type(x) == 'string' then
connection = x
x = nil
y = nil
end
self.currentLayer:add({ type='component', connection=connection, componentBuilder=componentBuilder, x=x, y=y})
--[[
self.innards[#self.innards + 1] = clsTable(...)
return self
]]