Skip to content

Commit

Permalink
import code from CS50 repository
Browse files Browse the repository at this point in the history
  • Loading branch information
lukaszblad committed Jun 29, 2024
1 parent 41186a5 commit 610cddb
Show file tree
Hide file tree
Showing 58 changed files with 2,282 additions and 1 deletion.
8 changes: 7 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
@@ -1,2 +1,8 @@
# Timber50
2D pixel-art game created in Lua LÖVE2D
## My final project for CS50 Games
In this retro-style arcade game, you play as a lumberjack, chopping down trees while avoiding branches. The game captures the addictive and simple gameplay of the original Timberman, featuring pixel art graphics and responsive controls. Tap left or right to chop, but be quick and precise to achieve high scores without getting hit by branches.

## Gameplay
[![Timber50 Gameplay YouTube](https://img.youtube.com/vi/uK2yEr9cpQg/0.jpg)](https://www.youtube.com/watch?v=uK2yEr9cpQg) <br>
Youtube

Binary file added fonts/fipps/Fipps-Regular.otf
Binary file not shown.
Binary file added fonts/fipps/pheist_license_freeware.pdf
Binary file not shown.
Binary file added fonts/jaro/Jaro-Regular.ttf
Binary file not shown.
Binary file added fonts/jaro/Jaro24pt-Regular.ttf
Binary file not shown.
Binary file added fonts/jaro/Jaro48pt-Regular.ttf
Binary file not shown.
Binary file added fonts/jaro/Jaro6pt-Regular.ttf
Binary file not shown.
Binary file added fonts/jaro/Jaro72pt-Regular.ttf
Binary file not shown.
Binary file added fonts/karma/Karma Future.otf
Binary file not shown.
Binary file added fonts/karma/Karma Suture.otf
Binary file not shown.
5 changes: 5 additions & 0 deletions fonts/karma/license.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
The fonts included in this archive are released under a �no rights reserved� Creative Commons Zero license. Please do not ask permission to do anything with these fonts. Whatever you want to do with this font, the answer will be yes. Please read about the CC0 Public Domain license before contacting me.

https://creativecommons.org/publicdomain/zero/1.0/

To the extent possible under law, Raymond Larabie has waived all copyright and related or neighboring rights to the fonts in this archive. This work is published from: Japan.
Binary file added graphics/backgrounds.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphics/branches.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphics/characters.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphics/gui.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added graphics/sprites.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
98 changes: 98 additions & 0 deletions libraries/class.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
--[[
Copyright (c) 2010-2013 Matthias Richter
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.
Except as contained in this notice, the name(s) of the above copyright holders
shall not be used in advertising or otherwise to promote the sale, use or
other dealings in this Software without prior written authorization.
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 function include_helper(to, from, seen)
if from == nil then
return to
elseif type(from) ~= 'table' then
return from
elseif seen[from] then
return seen[from]
end

seen[from] = to
for k,v in pairs(from) do
k = include_helper({}, k, seen) -- keys might also be tables
if to[k] == nil then
to[k] = include_helper({}, v, seen)
end
end
return to
end

-- deeply copies `other' into `class'. keys in `other' that are already
-- defined in `class' are omitted
local function include(class, other)
return include_helper(class, other, {})
end

-- returns a deep copy of `other'
local function clone(other)
return setmetatable(include({}, other), getmetatable(other))
end

local function new(class)
-- mixins
class = class or {} -- class can be nil
local inc = class.__includes or {}
if getmetatable(inc) then inc = {inc} end

for _, other in ipairs(inc) do
if type(other) == "string" then
other = _G[other]
end
include(class, other)
end

-- class implementation
class.__index = class
class.init = class.init or class[1] or function() end
class.include = class.include or include
class.clone = class.clone or clone

-- constructor call
return setmetatable(class, {__call = function(c, ...)
local o = setmetatable({}, c)
o:init(...)
return o
end})
end

-- interface for cross class-system compatibility (see https://github.com/bartbes/Class-Commons).
if class_commons ~= false and not common then
common = {}
function common.class(name, prototype, parent)
return new{__includes = {prototype, parent}}
end
function common.instance(class, ...)
return class(...)
end
end


-- the module
return setmetatable({new = new, include = include, clone = clone},
{__call = function(_,...) return new(...) end})
15 changes: 15 additions & 0 deletions libraries/knife/base.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
return {
extend = function (self, subtype)
subtype = subtype or {}
local meta = { __index = subtype }
return setmetatable(subtype, {
__index = self,
__call = function (self, ...)
local instance = setmetatable({}, meta)
return instance, instance:constructor(...)
end
})
end,
constructor = function () end,
}

78 changes: 78 additions & 0 deletions libraries/knife/behavior.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
-- behavior.lua -- a state manager

-- internal/external api

local function getCurrentFrame (behavior)
return behavior.states[behavior.state][behavior.index]
end

local function advanceFrame (behavior)
local nextState = behavior.frame.after
local nextIndex = behavior.index + 1
local maxIndex = #behavior.states[behavior.state]

if nextState then
behavior.state = nextState
nextIndex = 1
elseif nextIndex > maxIndex then
nextIndex = 1
end

behavior.index = nextIndex
behavior.frame = behavior:getCurrentFrame()
end

local function performAction (behavior)
local act = behavior.frame.action

if act then
act(behavior, behavior.subject)
end
end

-- external api

local function update (behavior, dt)
behavior.elapsed = behavior.elapsed + dt

while behavior.elapsed >= behavior.frame.duration do
behavior.elapsed = behavior.elapsed - behavior.frame.duration
behavior:advanceFrame()
behavior:performAction()
end

return behavior
end

local function setState (behavior, state, index)
behavior.state = state
behavior.index = index or 1
behavior.elapsed = 0
behavior.frame = behavior:getCurrentFrame()
behavior:performAction()
return behavior
end

-- behavior factory

return function (states, subject)
local behavior = {
states = states,
subject = subject,
elapsed = 0,
state = 'default',
index = 1,
-- internal api
getCurrentFrame = getCurrentFrame,
advanceFrame = advanceFrame,
performAction = performAction,
-- external api
update = update,
setState = setState
}

behavior.frame = behavior:getCurrentFrame()
behavior:performAction()

return behavior
end
27 changes: 27 additions & 0 deletions libraries/knife/bind.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,27 @@
local loadstring = _G.loadstring or _G.load
local tconcat = table.concat

local helperCache = {}

local function buildHelper (argCount)
if helperCache[argCount] then
return helperCache[argCount]
end
local argList1 = { 'f' }
local argList2 = {}
for index = 1, argCount do
argList1[index + 1] = 'a' .. index
argList2[index] = 'a' .. index
end
argList2[argCount + 1] = '...'
local source = 'return function(' .. tconcat(argList1, ', ') ..
') return function(...) return f(' .. tconcat(argList2, ', ') ..
') end end'
local helper = loadstring(source)()
helperCache[argCount] = helper
return helper
end

return function (func, ...)
return buildHelper(select('#', ...))(func, ...)
end
31 changes: 31 additions & 0 deletions libraries/knife/chain.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
local function Invoker (links, index)
return function (...)
local link = links[index]
if not link then
return
end
local continue = Invoker(links, index + 1)
local returned = link(continue, ...)
if returned then
returned(function (_, ...) continue(...) end)
end
end
end

return function (...)
local links = { ... }

local function chain (...)
if not (...) then
return Invoker(links, 1)(select(2, ...))
end
local offset = #links
for index = 1, select('#', ...) do
links[offset + index] = select(index, ...)
end
return chain
end

return chain
end

54 changes: 54 additions & 0 deletions libraries/knife/convoke.lua
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
return function (routine)
local routines = { routine }
local routineIndex = 1
local isFinished = false

local function execute ()
local continueCount = 0
local run

local function continue ()
continueCount = continueCount + 1
return function (...)
continueCount = continueCount - 1
if continueCount == 0 then
return run(...)
end
end
end

local function wait (...)
return coroutine.yield(...)
end

local r = coroutine.create(function ()
isFinished = false
while routineIndex <= #routines do
routines[routineIndex](continue, wait)
continueCount = 0
routineIndex = routineIndex + 1
end
isFinished = true
end)

run = function (...)
return coroutine.resume(r, ...)
end

run()
end

local function appendOrExecute (routine)
if routine then
routines[#routines + 1] = routine
if isFinished then
execute()
end
return appendOrExecute
else
execute()
end
end

return appendOrExecute
end
Loading

0 comments on commit 610cddb

Please sign in to comment.