Skip to content

Instantly share code, notes, and snippets.

@tarrouye
Last active August 29, 2015 14:04
Show Gist options
  • Save tarrouye/cce08f9c984ed81440dd to your computer and use it in GitHub Desktop.
Save tarrouye/cce08f9c984ed81440dd to your computer and use it in GitHub Desktop.
Ladderman Gist
--# Main
-- Ladderman
displayMode(FULLSCREEN)
supportedOrientations(PORTRAIT)
function setup()
LOADINGIMGS, PLAYING, LOST = 1, 2, 3
imgLoader = Loader()
MODE = LOADINGIMGS
end
function afterImgSetup()
MODE = PLAYING
stuffs()
initialise()
end
function draw()
background(255)
if MODE == LOADINGIMGS then
imgLoader:draw()
if imgLoader.doneLoading then
afterImgSetup()
end
end
if MODE == PLAYING or MODE == LOST then
drawGame()
end
if MODE == LOST then
drawLost()
end
end
function touched(t)
if t.state == ENDED then
if MODE == PLAYING then
touchPlaying(t)
elseif MODE == LOST then
touchLost(t)
end
end
end
--# Playing
-- Just holds most of the functions for the playing state
-- Resets the game
function initialise()
ladders = {}
player = { x = rightX, y = sizes.ladder.y * 2.5, cid = math.random(1, 5), iid = 1, angle = 0 }
sign = { x = 0, y = sizes.ladder.y + sizes.sign.y / 2, alpha = 0 }
for r = 1, math.ceil(HEIGHT / sizes.ladder.y) + 1 do
addRow(true)
end
groundO = sizes.ladder.y
score = 0
highscore = readLocalData("highscore") or 0
time = .5
if timeT ~= nil then tween.stop(timeT) end
canMove = true
fell = false
end
-- Draws everything for the playing state
function drawGame()
-- Draw the 'bulding' background
for bi = #ladders, 1, -2 do
sprite(imgs.brick, WIDTH / 2, ladders[bi].y, WIDTH, sizes.ladder.y)
end
-- Draw the ladders
for li = #ladders, 1, -1 do
local ladder = ladders[li]
if not ladder.hole then
sprite(imgs.ladder, ladder.x, ladder.y, sizes.ladder.x, sizes.ladder.y)
else
sprite(imgs.hole, ladder.x, ladder.y, sizes.ladder.x, sizes.ladder.y)
end
end
-- Draw the player
pushMatrix() translate(player.x, player.y) rotate(player.angle)
sprite(imgs.player[player.cid][player.iid], 0, 0, sizes.player.x, sizes.player.y)
popMatrix()
-- Draw the ground if it is still onscreen
if groundO < sizes.ladder.y then
sprite(imgs.ground, WIDTH / 2, sizes.ladder.y / 2 - groundO, WIDTH, sizes.ladder.y)
end
-- Draw the timer bar
local o = WIDTH / 200
local a = (rightX - sizes.ladder.x / 2) - (leftX + sizes.ladder.x / 2)
sprite(imgs.bar[1], WIDTH / 2, HEIGHT - HEIGHT / 40, a, HEIGHT / 20)
sprite(imgs.bar[2], WIDTH / 2, HEIGHT - HEIGHT / 40, (a - o*1.8) * time, HEIGHT / 20 - o*1.8)
-- Draws the score and then the highscore right below it
sprite(imgs.panel, WIDTH / 2, HEIGHT / 2, sizes.replay.x)
font(GAMEFONT)
fill(0) if score >= highscore then fill(255,0,0) end fontSize(WIDTH / 10)
text(score, WIDTH / 2, HEIGHT / 2)
fill(255,0,0) fontSize(WIDTH / 20)
text(math.max(highscore, score), WIDTH / 2, HEIGHT / 2 - fontSize() * 1.5)
fill(0)
text("SCORE", WIDTH / 2, HEIGHT / 2 + fontSize() * 1.5)
stroke(0, 155, 255, 153) strokeWidth(oneS * 2)
line(WIDTH / 2 - sizes.replay.x / 2.17, HEIGHT / 2 - fontSize(), WIDTH / 2 + sizes.replay.x / 2.17, HEIGHT / 2 - fontSize())
line(WIDTH / 2 - sizes.replay.x / 2.17, HEIGHT / 2 + fontSize(), WIDTH / 2 + sizes.replay.x / 2.17, HEIGHT / 2 + fontSize())
-- Lost / died sign
tint(255, sign.alpha)
sprite(imgs.sign, sign.x, sign.y, sizes.sign.x, sizes.sign.y)
noTint()
end
-- Losing sequence
function fall()
canMove = false
fell = true
sounds.fall()
if timeT ~= nil then tween.stop(timeT) end
tween(.75, _G, { groundO = 0 })
falling = tween(.75, player, { y = 0, angle = 230 }, tween.easing.linear, function()
sounds.die()
sign.x = player.x + sizes.ladder.x / 2 + sizes.sign.x / 1.75
if player.x == leftX then sign.x = player.x - sizes.ladder.x / 2 - sizes.sign.x / 1.75 end
falling = tween(.5, sign, { alpha = 255 }, tween.easing.linear, function()
animateEndMenu()
MODE = LOST
end)
end)
end
-- Adds another row to the top of the ladder
function addRow(rnok)
local y
if #ladders == 0 then y = sizes.ladder.y / 2
else y = ladders[#ladders].y + sizes.ladder.y end
local rand = math.random(1, 5)
local rhole, lhole = false, false
if not rnok then
if rand == 2 and lastRand ~= 3 then rhole = true
elseif rand == 3 and lastRand ~= 2 then lhole = true end
end
lastRand = rand
table.insert(ladders, { x = rightX, y = y, hole = rhole })
table.insert(ladders, { x = leftX, y = y, hole = lhole })
end
-- Checks if the player is in a hole
function checkLoss()
if fell then return true end
for li = #ladders, 1, -1 do
local ladder = ladders[li]
if ladder.hole and ladder.x == player.x and math.abs(ladder.y - player.y) < sizes.ladder.y / 2 then
if score > highscore then
saveLocalData("highscore", score)
end
fall()
return true
end
end
return false
end
-- Moves ladders and player, and calls to check if player is in a hole
function moveObjects(right)
canMove = false
player.iid = 2
sounds.climb()
if right then
player.x = rightX
else
player.x = leftX
end
checkLoss()
for li = #ladders, 1, -1 do
local ladder = ladders[li]
tween(0.04, ladder, { y = ladder.y - sizes.ladder.y })
if ladder.y < 0 then
table.remove(ladders, li)
end
end
tween.delay(0.04, function()
addRow()
if not checkLoss() then
player.iid = 1
score = score + 1
canMove = true
end
end)
end
-- Adds a bit of time to the timer
function addToTimer()
if timeT ~= nil then
tween.stop(timeT)
timeT = nil
end
time = math.min(time + .04, 1)
timeT = tween(time * 8, _G, { time = 0 }, tween.easing.linear, fall)
end
-- All the touch code for the playing state
function touchPlaying(t)
if canMove then
moveObjects(t.x > WIDTH / 2)
addToTimer()
end
end
--# Lost
-- Just holds most of the functions for the lost state
function animateEndMenu()
tween(.5, replay, { y = HEIGHT / 2 - sizes.replay.x - sizes.replay.y})
end
function animateHideEndMenu()
tween(.5, replay, { y = -sizes.replay.y / 2 }, tween.easing.linear, function()
initialise()
MODE = PLAYING
end)
end
function drawLost()
sprite(imgs.panel, replay.x, replay.y, sizes.replay.x, sizes.replay.y)
stroke(0, 155, 255, 153) strokeWidth(oneS * 2)
local lof, sof, tof = sizes.replay.x / 2.17, sizes.replay.y / 4, sizes.replay.y / 9
--line(replay.x - lof, replay.y - sof, replay.x + lof, replay.y - sof)
--line(replay.x - lof, replay.y + sof, replay.x + lof, replay.y + sof)
fill(0) fontSize(sizes.replay.y * .6)
text("AGAIN?", replay.x, replay.y)
end
function touchLost(t)
if t.x >= replay.x - sizes.replay.x / 2 and t.x <= replay.x + sizes.replay.x / 2
and t.y >= replay.y - sizes.replay.y / 2 and t.y <= replay.y + sizes.replay.y / 2 then
animateHideEndMenu()
end
end
--# Variables
function stuffs()
GAMEFONT = "Futura-CondensedMedium"
oneS = WIDTH / 768
sounds = {
climb = function() sound("A Hero's Quest:Swing 3") end,
fall = function() sound("A Hero's Quest:Hurt 4") end,
die = function() sound("A Hero's Quest:Hurt 5") end
}
local bimg, gimg = makeImgs()
imgs = {
ladder = readImage("Documents:LMLadder"),
hole = readImage("Documents:LMHole"),
player = {
{ readImage("Documents:LMPlayerB1"), readImage("Documents:LMPlayerB2") },
{ readImage("Documents:LMPlayerL1"), readImage("Documents:LMPlayerL2") },
{ readImage("Documents:LMPlayerP1"), readImage("Documents:LMPlayerP2") },
{ readImage("Documents:LMPlayerG1"), readImage("Documents:LMPlayerG2") },
{ readImage("Documents:LMPlayerY1"), readImage("Documents:LMPlayerY2") },
},
ground = gimg,
sign = readImage("Documents:LMRipsign"),
brick = bimg,
bar = { readImage("Documents:LMBargray"), readImage("Documents:LMBarred") },
panel = readImage("Documents:LMGlasspanel")
}
sizes = {
ladder = vec2(WIDTH / 9, HEIGHT / 9),
player = vec2(WIDTH / 10, HEIGHT / 9.5),
sign = vec2(WIDTH / 8, HEIGHT / 9),
replay = vec2(WIDTH / 4.725, WIDTH / 9)
}
replay = { x = WIDTH / 2, y = -sizes.replay.y / 2 }
leftX = WIDTH / 3.5
rightX = WIDTH * 2.5/3.5
end
function makeImgs()
local brickImg = image(WIDTH, HEIGHT / 9) setContext(brickImg)
for i = 1, 9 do
sprite("Documents:LMStone", -WIDTH / 18 + (WIDTH / 9) * i, HEIGHT / 18, WIDTH / 9, HEIGHT / 9)
end
setContext()
local groundImg = image(WIDTH, HEIGHT / 9) setContext(groundImg)
for i = 1, 9 do
sprite("Documents:LMGrass", -WIDTH / 18 + (WIDTH / 9) * i, HEIGHT / 18, WIDTH / 9, HEIGHT / 9)
end
setContext()
return brickImg, groundImg
end
--# ImagesToLoad
ImagesToLoad = {
{ spriteKey = "Documents:LMLadder", url = "http://i.imgur.com/xIqzbtJ.png" },
{ spriteKey = "Documents:LMHole", url = "http://i.imgur.com/o3a08eD.png" },
{ spriteKey = "Documents:LMPlayerB1", url = "http://i.imgur.com/lZBuLGQ.png" },
{ spriteKey = "Documents:LMPlayerB2", url = "http://i.imgur.com/eSj4r9g.png" },
{ spriteKey = "Documents:LMPlayerG1", url = "http://i.imgur.com/api8OpI.png" },
{ spriteKey = "Documents:LMPlayerG2", url = "http://i.imgur.com/86vF38r.png" },
{ spriteKey = "Documents:LMPlayerL1", url = "http://i.imgur.com/ZqLSUj2.png" },
{ spriteKey = "Documents:LMPlayerL2", url = "http://i.imgur.com/gfKRLMi.png" },
{ spriteKey = "Documents:LMPlayerP1", url = "http://i.imgur.com/x2vI7Gk.png" },
{ spriteKey = "Documents:LMPlayerP2", url = "http://i.imgur.com/U7860TA.png" },
{ spriteKey = "Documents:LMPlayerY1", url = "http://i.imgur.com/LQndLGf.png" },
{ spriteKey = "Documents:LMPlayerY2", url = "http://i.imgur.com/kfE2Yal.png" },
{ spriteKey = "Documents:LMRipsign", url = "http://i.imgur.com/OVaoNjo.png" },
{ spriteKey = "Documents:LMBargray", url = "http://i.imgur.com/gSB7EAr.png" },
{ spriteKey = "Documents:LMBarred", url = "http://i.imgur.com/5TDecbn.png" },
{ spriteKey = "Documents:LMGlasspanel", url = "http://i.imgur.com/rkz6v3L.png" },
{ spriteKey = "Documents:LMStone", url = "http://i.imgur.com/5dnSgbO.png" },
{ spriteKey = "Documents:LMGrass", url = "http://i.imgur.com/sjnBImb.png" },
}
--# Loader
Loader = class()
function Loader:init()
self.loaded = 0
self.loading = nil
self.doneLoading = false
self.onEnterTime = 0
self.colour = color(0, 133, 255, 255)
self.circSize = (WIDTH / 3)*2 + 40
self.displayErrorMessage = false
self.queue = {}
self:onEnter()
end
function Loader:onEnter()
self.loaded = 0
self.loading = nil
self.doneLoading = false
self.changing = nil
self.onEnterTime = ElapsedTime
self.displayErrorMessage = false
self.queue = {}
self:loadImages()
end
function Loader:loadImages()
for id, stuff in ipairs(ImagesToLoad) do
if readImage(stuff.spriteKey) == nil then
self:addToQueue(stuff)
else
self.loaded = self.loaded + 1
end
end
self:checkQueue()
end
function Loader:addToQueue(stuff)
table.insert(self.queue, stuff)
self:checkQueue()
end
function Loader:checkQueue()
if self.loaded == #ImagesToLoad then
self.doneLoading = true
end
for id, stuff in ipairs(self.queue) do
if id == 1 and self.loading == nil then
self:load(stuff)
self.loading = "busy"
table.remove(self.queue, id)
end
end
end
function Loader:load(stuff)
local saveThenNext = function(img)
saveImage(stuff.spriteKey, img)
self.loaded = self.loaded + 1
self.loading = nil
self:checkQueue()
end
--[[local getActualUrl = function(data)
local check = '<meta content="Shared with Dropbox" property="og:description" /><meta content="(.*)" property="og:image" />'
--local a, b = data:find(';\nShmodelPreview.init_photo("', 1, true)
--local c, d = data:find('", ', b, true)
--local acUrl = data:sub(b+1, c-1)
local acUrl = data:match(check)
http.request(acUrl, saveThenNext, function() self:failed() end)
end]]
http.request(stuff.url, saveThenNext, function() self:failed() end)
end
function Loader:failed()
self.displayErrorMessage = true
end
function Loader:draw()
background(255)
if self.displayErrorMessage == false then
pushStyle()
stroke(self.colour) noFill() strokeWidth(1)
ellipse(WIDTH/2, HEIGHT/2, self.circSize)
font("HelveticaNeue-Light") fontSize(35)
fill(self.colour)
text("Loading", WIDTH/2, fontSize())
for i = 1, #ImagesToLoad do
stroke(self.colour) strokeWidth(2)
noFill()
if self.loaded >= i then
fill(self.colour)
end
local perRow = 6
local spacing, size = 50, 25
local rows = math.ceil(#ImagesToLoad / perRow)
local row = math.ceil(i / perRow)
local off = rows / 2
local startY = HEIGHT/2 + off * size + off * spacing
local y = startY - size * (row-0.5) - spacing * (row-0.5)
local inRow = i - ((row-1) * perRow)
local startX = WIDTH/2 - (perRow/2 * size) - (perRow/2 * spacing)
local x = startX + size * (inRow-0.5) + spacing * (inRow-0.5)
ellipse(x, y, size)
end
popStyle()
else
font(STANDARDFONT) fontSize(35)
fill(38, 38, 38, 255) textAlign(CENTER)
text("An Error Occured. Please Check\nYour Internet And Reload Codea.", WIDTH/2, HEIGHT/2)
end
end
function Loader:touched(touch)
-- Codea does not automatically call this method
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment