-
-
Save SkyTheCoder/7c9d7350d5d573459d90 to your computer and use it in GitHub Desktop.
FallDodge, my Codea Cook-Off competition entry from a while ago.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
--# Highscores | |
Highscores = class() | |
function Highscores:init() | |
--ScoreTracker(project,success callback, fail callback) | |
--s.results holds the returned results in a table. | |
self.data = {a = 0, b = 0} | |
self.tweened = {a = 0, b = 0} | |
self.tweens = {a = -1337, b = -1337} | |
self.scores = {} | |
self.name = "" | |
self.s = ScoreTracker("FallDodge",function(d) | |
table.sort(self.s.results, function(a, b) | |
return a[2] > b[2] | |
end) | |
self.scores = self.s.results | |
self.s.results = {} | |
print("High Scores!\n") | |
for i,j in pairs(self.s.results) do | |
print("Rank "..i.."\nUser: "..j[1].. | |
"\nScore: "..j[2].. | |
"\nField1: "..j[3].. | |
"\nField2: "..j[4].. | |
"\nField3: "..j[5]) | |
end | |
end) -- setup score tracker | |
--This will create a new entry | |
--s:submit("test user","999","level 1","lives 2") | |
--This returns the entry. | |
tween.delay(2, function() | |
self:get() | |
end) | |
end | |
function Highscores:get() | |
self.s:request() | |
end | |
function Highscores:draw() | |
pushStyle() | |
pushMatrix() | |
background(255) | |
font("Copperplate-Light") | |
fontSize(48) | |
fill(0) | |
if newHighScore then | |
fontSize(24) | |
text("NEW PERSONAL BEST", 256, HEIGHT - 96) | |
fontSize(48) | |
end | |
text("HIGHSCORES", WIDTH / 2, HEIGHT / 2 + 96) | |
fontSize(24) | |
for k, v in pairs(self.scores) do | |
if k <= 5 then | |
text(v[1] .. ": " .. string.format("%18.0f", tonumber(v[2])), WIDTH / 2, HEIGHT / 2 - ((k - 1) * 36)) | |
end | |
end | |
fontSize(36) | |
text("SUBMIT YOUR SCORE", WIDTH / 2, 192) | |
if self.textbox then | |
background(255) | |
text("ENTER YOUR NAME", WIDTH / 2, HEIGHT / 2 + 96) | |
fontSize(24) | |
self.name = keyboardBuffer() | |
local renderName = self.name | |
if isKeyboardShowing() and math.sin(4 * ElapsedTime) >= 0 then | |
renderName = renderName .. "|" | |
end | |
text(renderName, WIDTH / 2, HEIGHT / 2) | |
end | |
fontSize(24) | |
fill(self.data.b) | |
text("Back", WIDTH / 2, 96) | |
popStyle() | |
popMatrix() | |
end | |
function Highscores:touched(touch) | |
local time = 0.25 | |
pushStyle() | |
font("Copperplate-Light") | |
fontSize(36) | |
local w, h = textSize("SUBMIT YOUR SCORE") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(192 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.a == 0 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 128}) | |
self.tweened.a = 1 | |
end | |
else | |
if self.tweened.a == 1 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
self.tweened.a = 0 | |
self.textbox = true | |
showKeyboard() | |
end | |
end | |
else | |
if self.tweens.a ~= -1337 and self.tweened.a == 1 then | |
tween.stop(self.tweens.a) | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
end | |
self.tweened.a = 0 | |
end | |
local w, h = textSize("Back") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.b == 0 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 128}) | |
self.tweened.b = 1 | |
end | |
else | |
if self.tweened.b == 1 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
self.tweened.b = 0 | |
state = 1 | |
end | |
end | |
else | |
if self.tweens.b ~= -1337 and self.tweened.b == 1 then | |
tween.stop(self.tweens.b) | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
end | |
self.tweened.b = 0 | |
end | |
if touch.state == ENDED and not isKeyboardShowing() and self.textbox then | |
showKeyboard() | |
end | |
popStyle() | |
end | |
function Highscores:keyboard(key) | |
if key == RETURN then | |
self.textbox = false | |
hideKeyboard() | |
self.s:submit(self.name, math.floor(states[2].score)) | |
tween.delay(2, function() | |
self:get() | |
end) | |
end | |
end | |
--# LoaderInfo | |
LoaderInfo = class() | |
function LoaderInfo:init() | |
self.a = { | |
"Interpolating", | |
"Splining", | |
"Training", | |
"Downloading", | |
"Converting", | |
"Ionizing", | |
"Teleporting", | |
"Transporting", | |
"Atomizing", | |
"Sculpting", | |
"Targetting", | |
"Lazering", | |
"Lazerizing", | |
"Exploding", | |
"Imploding", | |
"Exterminating", | |
"Deleting", | |
} | |
self.b = { | |
"Shiny", | |
"Wibbly-wobbly", | |
"Timey-wimey", | |
"Oddly Shaped", | |
"Spherical", | |
"Decomposed", | |
"Monkey", | |
"Machine", | |
"Machinima", | |
"Sanitized", | |
"Square", | |
"Blocky", | |
"Cube-y", | |
"Friendly", | |
"Mean", | |
"Meaty", | |
"Annoying", | |
"Perfectly Normally Shaped", | |
"Terrifying", | |
"Very", | |
} | |
self.c = { | |
"Monkeys (not apes)", | |
"Pandas", | |
"Gorillas (not monkeys)", | |
"Apes (not gorillas)", | |
"Walruses (koo-koo-ka-choo)", | |
"Terrifying Butterflies", | |
"Butterflies of Terror", | |
"Mechanical Bulls", | |
"TARDISes", | |
"Doctors", | |
"Minecrafts", | |
"Minecraft Worlds", | |
"Jerks", | |
"Old-Timey Time Watches", | |
"Jelly Babies", | |
"Laptops", | |
"Squirrels", | |
"Adorable Puppies", | |
"Christmas Goats", | |
} | |
end | |
function LoaderInfo:getPhrase() | |
local a = self.a[math.random(1, #self.a)] | |
local b = self.b[math.random(1, #self.b)] | |
local c = self.c[math.random(1, #self.c)] | |
return a .. " " .. b .. " " .. c | |
end | |
--# Lose | |
Lose = class() | |
function Lose:init() | |
self.bgSprites = { | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Documents:DL-Asset-rock"), | |
readImage("Documents:DL-Asset-mushroom_red"), | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Documents:DL-Asset-spring_pushed"), | |
readImage("Platformer Art:Guy Look Right"), | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Platformer Art:Mushroom"), | |
} | |
self.offsets = { | |
50, | |
85, | |
85, | |
50, | |
75, | |
90, | |
50, | |
85, | |
} | |
self.angleOffset = 0 | |
self.data = {a = 0, b = 0} | |
self.tweened = {a = 0, b = 0} | |
self.tweens = {a = -1337, b = -1337} | |
end | |
function Lose:draw() | |
pushStyle() | |
pushMatrix() | |
background(255) | |
pushMatrix() | |
translate(WIDTH / 2, HEIGHT / 2 + 196) | |
rotate(self.angleOffset) | |
for k, v in ipairs(self.bgSprites) do | |
sprite(v, 0, self.offsets[k]) | |
rotate(360 / #self.bgSprites) | |
end | |
if isRecording() then | |
self.angleOffset = self.angleOffset + 0.5 | |
else | |
self.angleOffset = self.angleOffset + 0.5 * DeltaTime * 60 | |
end | |
popMatrix() | |
fill(0) | |
fontSize(48) | |
font("Copperplate-Light") | |
text("YOU LOST", WIDTH / 2, HEIGHT / 2 + 96) | |
text("YOUR SCORE: " .. string.format("%18.0f", math.floor(states[2].score)), WIDTH / 2, HEIGHT / 2) | |
fontSize(24) | |
fill(self.data.a) | |
text("Replay", WIDTH / 2, HEIGHT / 2 - 96) | |
fill(self.data.b) | |
text("Highscores", WIDTH / 2, 96) | |
popMatrix() | |
popStyle() | |
end | |
function Lose:touched(touch) | |
local time = 0.25 | |
pushStyle() | |
font("Copperplate-Light") | |
fontSize(24) | |
local w, h = textSize("Replay") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(HEIGHT / 2 - 96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.a == 0 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 128}) | |
self.tweened.a = 1 | |
end | |
else | |
if self.tweened.a == 1 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
self.tweened.a = 0 | |
state = 2 | |
states[2].score = 0 | |
end | |
end | |
else | |
if self.tweens.a ~= -1337 and self.tweened.a == 1 then | |
tween.stop(self.tweens.a) | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
end | |
self.tweened.a = 0 | |
end | |
local w, h = textSize("Highscores") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.b == 0 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 128}) | |
self.tweened.b = 1 | |
end | |
else | |
if self.tweened.b == 1 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
self.tweened.b = 0 | |
state = 4 | |
end | |
end | |
else | |
if self.tweens.b ~= -1337 and self.tweened.b == 1 then | |
tween.stop(self.tweens.b) | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
end | |
self.tweened.b = 0 | |
end | |
popStyle() | |
end | |
function Lose:keyboard(key) | |
end | |
--# Static | |
static = {} | |
--# Game | |
Game = class() | |
function Game:init() | |
newHighScore = false | |
self.genOff = 200 | |
self.offset = vec2(0, 0) | |
self.renderbg = RenderBG(self) | |
self.player = Player(self, 50, HEIGHT - 92) | |
tween(3, self.player.pos, {x = 200}, tween.easing.linear, function() | |
self.player.pose = 1 | |
tween.delay(1, function() | |
self.player.pose = 2 | |
end) | |
tween.delay(2, function() | |
tween.delay(0.5, function() | |
self.player.pose = 3 | |
end) | |
tween(1, self.player.pos, {y = HEIGHT - 86}, tween.easing.quadIn) | |
tween(1, self.player.aestheticAngle, {a = 45}, tween.easing.quadIn, function() | |
tween(1.5, self.player.aestheticAngle, {a = 0}, tween.easing.quadOut) | |
tween(1, self.player.pos, {x = 300, y = HEIGHT - 128}, tween.easing.quadIn, function() | |
self.player.move = true | |
self.player.moveY = true | |
end) | |
end) | |
end) | |
end) | |
self.objects = {} | |
self.generate = false | |
tween.delay(16, function() | |
self.generate = true | |
end) | |
self.done = false | |
self.types = { | |
Mushroom, | |
Spring, | |
Ledge, | |
} | |
self.weights = { | |
65, | |
20, | |
15 | |
} | |
self.pcount = 0 | |
self.score = 0 | |
end | |
function Game:gen() | |
local i = math.random(0, 1) | |
local type | |
while type == nil do | |
local cType = math.random(1, #self.weights) | |
local chance = self.weights[cType] | |
if math.random(0, 100) <= chance then | |
type = self.types[cType] | |
end | |
end | |
table.insert(self.objects, type(self, (WIDTH * 0.2 + i * (WIDTH * 0.6)) + (-i * 2 + 1) * 49, self.genOff)) | |
self.genOff = self.genOff - 200 | |
end | |
function Game:win() | |
self.player.move = false | |
self.player.dir = -1 | |
self.player.pose = 3 | |
tween(1, self.player.pos, {y = HEIGHT + 100}, tween.easing.quadOut, function() | |
tween(0.5, self.player.pos, {x = 200}, tween.easing.quadInOut, function() | |
tween(2, self.player.pos, {y = HEIGHT - 92}, tween.easing.quadIn, function() | |
self.player.pose = 5 | |
tween(3, self.player.pos, {x = 50}, tween.easing.linear, function() | |
self.player.pose = 2 | |
tween.delay(0.5, function() | |
self.player.dir = 1 | |
self.player.pose = 1 | |
tween.delay(0.5, function() | |
self.player.pose = 2 | |
tween.delay(0.5, function() | |
self.player.pose = 3 | |
self.player.breakScared = true | |
tween(1, self.player.pos, {y = HEIGHT - 64}, tween.easing.quadOut, function() | |
tween(1, self.player.pos, {y = HEIGHT - 92}, tween.easing.quadIn, function() | |
tween.delay(0.5, function() | |
self.player.pose = 2 | |
self.player.breakScared = false | |
self.player:lookScared() | |
tween.delay(0.5, function() | |
self.player.pose = 1 | |
tween.delay(0.5, function() | |
self.player.pose = 2 | |
self.player.dir = -1 | |
tween.delay(0.5, function() | |
self.player.pose = 5 | |
tween(3, self.player.pos, {x = -100}, tween.easing.linear, function() | |
--print("DONE") | |
--displayMode(STANDARD) | |
self.done = true | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end | |
function Game:minusPcount() | |
self.pcount = self.pcount - 1 | |
end | |
function Game:plusPcount() | |
self.pcount = self.pcount + 1 | |
end | |
function Game:draw() | |
if self.player.move then | |
self.score = self.score + DeltaTime * 5 | |
self.score = self.score + math.max(0, self.player.motY) * DeltaTime * 5 | |
end | |
if math.floor(self.player.pos.y / 46) <= -256 then | |
state = 5 | |
end | |
for k, v in ipairs(self.objects) do | |
if v.type == "ledge" then | |
self.pcount = self.pcount + 1 | |
end | |
end | |
--print(static.ledge.pcount) | |
pushStyle() | |
pushMatrix() | |
translate(self.offset.x, self.offset.y) | |
self.renderbg:draw() | |
self.player:draw() | |
for k, v in ipairs(self.objects) do | |
v:draw() | |
end | |
if self.generate then | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
if self.player.pos.y <= self.genOff + HEIGHT * 3 then | |
self:gen() | |
end | |
end | |
if self.done then | |
fontSize(48) | |
--text("YOU WON!!!", WIDTH / 2, HEIGHT / 2) | |
state = 3 | |
if self.score > readGlobalData("FallDodge.Highscore", 0) then | |
newHighScore = true | |
saveGlobalData("FallDodge.Highscore", self.score) | |
end | |
end | |
popMatrix() | |
popStyle() | |
if self.pcount == 0 and self.player.onLedge then | |
self.player.onLedge = false | |
self.player.pose = 3 | |
--self.player.moveY = true | |
end | |
self.pcount = 0 | |
--static.ledge.setPCount(0) | |
font("Copperplate-Light") | |
fontSize(24) | |
color(0) | |
text("YOUR SCORE: " .. string.format("%18.0f", self.score), WIDTH / 2, HEIGHT - 48) | |
end | |
function Game:getObj(id) | |
return self.objects[id] or {pos = {y = 0}} | |
end | |
function Game:touched(touch) | |
self.player:touched(touch) | |
end | |
function Game:keyboard(key) | |
end | |
--# Ledge | |
static.ledge = { -- Static variables, the same for all classes | |
pcount = 0 | |
} | |
Ledge = class() | |
function Ledge:init(game, x, y) | |
self.game = game | |
self.pos = vec2(x, y) | |
self.img = readImage("Documents:DL-Asset-stone_ledge_left") | |
self.dir = 1 | |
self:calcDir() | |
self.bounceTime = 0 | |
self.type = "ledge" | |
self.setPlayerAnim = false | |
end | |
function Ledge:calcDir() | |
if self.pos.x <= WIDTH / 2 then | |
self.dir = 1 | |
else | |
self.dir = -1 | |
end | |
end | |
function static.ledge.setPCount(n) | |
static.ledge.pcount = n | |
end | |
function Ledge:draw() | |
self.game:minusPcount() | |
--static.ledge.pcount = static.ledge.pcount - 1 | |
if math.abs(self.game.player.pos.y - self.pos.y) <= 80 and math.abs(self.game.player.pos.x - self.pos.x) <= 60 then | |
--print("COLLISION") | |
if self.game.player.pos.y < self.pos.y - 20 then | |
--print("UNDER") | |
self.game.player.motY = math.abs(self.game.player.motY * 0.5) | |
self.game.player.pos.y = self.game.player.pos.y - 5 | |
else | |
--print("TOP") | |
self.game:plusPcount() | |
--static.ledge.pcount = static.ledge.pcount + 1 | |
if self.bounceTime <= 3 then | |
--print("BOUNCE") | |
self.game.player.motY = -math.abs(self.game.player.motY * 0.5) | |
self.bounceTime = self.bounceTime + 1 | |
else | |
self.game.player.pos.y = self.pos.y + 80 | |
--print("STAY") | |
--self.game.player.moveY = false | |
self.game.player.onLedge = true | |
if math.abs(self.game.player.motX) >= 0.5 then | |
--print("FAST") | |
if not self.setPlayerAnim then | |
self.game.player.pose = 5 | |
self.setPlayerAnim = true | |
end | |
else | |
--print("SLOW") | |
if self.setPlayerAnim then | |
self.game.player.pose = 1 | |
self.setPlayerAnim = false | |
end | |
end | |
end | |
end | |
elseif math.abs(self.game.player.pos.x - self.pos.x) > 60 then | |
--print("OFF SIDE") | |
self.bounceTime = 0 | |
end | |
if self.bounceTime ~= 0 and self.game.player.pos:dist(self.pos) > 200 then | |
--print("FAR") | |
self.bounceTime = 0 | |
end | |
--print(self.bounceTime) | |
pushStyle() | |
pushMatrix() | |
translate(self.pos.x, self.pos.y) | |
sprite(self.img, 0, 0, self.dir * self.img.width, self.img.height) | |
popMatrix() | |
popStyle() | |
end | |
--# Main | |
--The name of the project must match your Codea project name if dependencies are used. | |
--Project: FallDodge | |
--Version: Alpha 1.5.1 | |
--Comments: | |
-- FallDodge | |
displayMode(FULLSCREEN) | |
-- Use this function to perform your initial setup | |
function setup() | |
dl_meta_url = "https://dl.dropboxusercontent.com/s/hm3h54zodpjohq7/info.dl_meta?dl=1&token_hash=AAGtxlx5b7xN6mFfly97HNUAkMnmh8pFmBWkzE1WRkW6Nw" | |
http.request(dl_meta_url, dl_meta_success, dl_meta_fail) | |
--startRecording() | |
print("Hello World!") | |
parameter.watch("1 / DeltaTime") | |
menu = Menu() | |
game = Game() | |
replay = Replay() | |
highscores = Highscores() | |
lose = Lose() | |
states = { | |
menu, | |
game, | |
replay, | |
highscores, | |
lose, | |
} | |
state = 1 | |
oldState = state | |
ready = false | |
animStart = 0 | |
needToGet = 1 | |
gotten = 0 | |
introData = {0, 0, 0, 0} | |
introFiles = { | |
readImage("Documents:DL-Asset-intro_1"), | |
readImage("Documents:DL-Asset-intro_2"), | |
readImage("Documents:DL-Asset-intro_3"), | |
readImage("Documents:DL-Asset-intro_4"), | |
} | |
readyForStates = false | |
readyForStatesDraw = false | |
showTouches = true | |
lineCount() | |
lInfo = LoaderInfo() | |
phrase = "" | |
loopPhrase() | |
getUrls = {} | |
end | |
function loopPhrase() | |
phrase = lInfo:getPhrase() | |
tween.delay(2, loopPhrase) | |
end | |
function dl_meta_success(meta, status, headers) | |
--print(meta) | |
local dls = {} | |
local valid = string.find(meta, "DL%-META\n%.-") | |
if valid then | |
print("Valid!") | |
local syntax = string.match(meta, "DL%-META\nSYNTAX (.-) END_SYNTAX\n") | |
syntax = string.gsub(syntax, "%$NEWLINE", "\n") | |
print("Syntax: " .. syntax) | |
for id, url, info in meta:match("DATA_START\n(.-)\nDATA_END"):gmatch(syntax) do | |
dls[#dls + 1] = {id = id, url = url, info = info} | |
print("ID: " .. id .. " URL: " .. url .. " Info: " .. info) | |
end | |
end | |
needToGet = #dls | |
--dlAssets(dls) | |
getUrls = dls | |
getNextAsset() | |
getNextAsset() | |
getNextAsset() | |
getNextAsset() | |
end | |
function getNextAsset() | |
if gotten < needToGet then | |
dlAsset(getUrls[gotten + 1].url, getUrls[gotten + 1].id, getUrls[gotten + 1].info) | |
gotten = gotten + 1 | |
end | |
end | |
function dlAsset(url, id, info) | |
http.request(url, function(img, status, headers) | |
if status == 200 and img ~= nil then | |
print("Downloaded asset " .. id .. " (AKA " .. info .. ") successfully") | |
saveImage("Documents:DL-Asset-" .. id, img) | |
end | |
getNextAsset() | |
end, function(err) | |
displayMode(STANDARD) | |
print("ERROR DOWNLOADING ASSET " .. id .. "(AKA " .. info .. "): " .. err) | |
if err == "Unable to create request (bad url?)" then | |
print("URL:") | |
print(url) | |
end | |
if err == "A connection failure occured" then | |
print("Try checking your internet connection") | |
end | |
getNextAsset() | |
end) | |
end | |
function dlAssets(dls) | |
if #dls > 0 then | |
for k, v in ipairs(dls) do | |
end | |
end | |
end | |
function dl_meta_fail(err) | |
print("ERROR FETCHING DOWNLOAD METADATA: " .. err) | |
if err == "A connection failure occurred" then | |
print("Try checking your internet connection") | |
end | |
print("Attempting to run anyways...") | |
gotten = needToGet | |
print("Running") | |
print("If any spots appear blank where they were not, this was because images were not downloaded") | |
end | |
-- This function gets called once every frame | |
function draw() | |
-- This sets a dark background color | |
background(40, 40, 50) | |
-- This sets the line thickness | |
strokeWidth(5) | |
-- Do your drawing here | |
background(255) | |
fill(0) | |
font("Copperplate-Light") | |
fontSize(48) | |
text("Loading", WIDTH / 2, HEIGHT / 2 + 48) | |
fontSize(36) | |
text(phrase, WIDTH / 2, HEIGHT / 2) | |
fontSize(24) | |
text(string.rep("O", gotten) .. string.rep("o", needToGet - gotten), WIDTH / 2, HEIGHT / 2 - 48) | |
text("Cancelling loading will cause the app to crash", WIDTH / 2, HEIGHT / 2 - 96) | |
if ready then | |
if readyForStatesDraw then | |
if state ~= oldState then | |
states[state]:init() | |
oldState = state | |
end | |
end | |
states[state]:draw() | |
tint(255, introData[1]) | |
sprite("Documents:DL-Asset-intro_1", WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT) | |
noTint() | |
for k, v in ipairs(introFiles) do | |
tint(255, introData[k]) | |
sprite(v, WIDTH / 2, HEIGHT / 2, WIDTH) | |
noTint() | |
end | |
elseif gotten >= needToGet then | |
lineCount() | |
ready = true | |
tween.stopAll() | |
tween(1, introData, {255, 0, 0, 0}, tween.easing.quadInOut, function() | |
readyForStatesDraw = true | |
tween.delay(1, function() | |
tween(1, introData, {255, 255, 0, 0}, tween.easing.quadInOut, function() | |
tween.delay(1, function() | |
tween(1, introData, {255, 255, 255, 0}, tween.easing.quadInOut, function() | |
tween.delay(2, function() | |
tween(1, introData, {255, 255, 255, 255}, tween.easing.quadInOut, function() | |
tween.delay(2, function() | |
tween(1, introData, {0, 0, 0, 0}, tween.easing.quadInOut, function() | |
readyForStates = true | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end) | |
end | |
pushStyle() | |
fill(32) | |
stroke(16, 128) | |
strokeWidth(8) | |
if isRecording() and showTouches and (CurrentTouch.state == BEGAN or CurrentTouch.state == MOVING) then | |
ellipse(CurrentTouch.x, CurrentTouch.y, 50, 50) | |
end | |
popStyle() | |
end | |
function touched(touch) | |
if readyForStates then | |
states[state]:touched(touch) | |
end | |
end | |
function keyboard(key) | |
if readyForStates then | |
states[state]:keyboard(key) | |
end | |
end | |
--# Menu | |
Menu = class() | |
function Menu:init() | |
self.bgSprites = { | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Documents:DL-Asset-rock"), | |
readImage("Documents:DL-Asset-mushroom_red"), | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Documents:DL-Asset-spring_pushed"), | |
readImage("Platformer Art:Guy Look Right"), | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Platformer Art:Mushroom"), | |
} | |
self.offsets = { | |
50, | |
85, | |
85, | |
50, | |
75, | |
90, | |
50, | |
85, | |
} | |
self.angleOffset = 0 | |
self.data = {a = 0, b = 0} | |
self.tweened = {a = 0, b = 0} | |
self.tweens = {a = -1337, b = -1337} | |
end | |
function Menu:draw() | |
pushStyle() | |
pushMatrix() | |
background(255) | |
pushMatrix() | |
translate(WIDTH / 2, HEIGHT / 2 + 128) | |
rotate(self.angleOffset) | |
for k, v in ipairs(self.bgSprites) do | |
sprite(v, 0, self.offsets[k]) | |
rotate(360 / #self.bgSprites) | |
end | |
if isRecording() then | |
self.angleOffset = self.angleOffset + 0.5 | |
else | |
self.angleOffset = self.angleOffset + 0.5 * DeltaTime * 60 | |
end | |
popMatrix() | |
fill(0) | |
fontSize(48) | |
font("Copperplate-Light") | |
text("FallDodge", WIDTH / 2, HEIGHT / 2) | |
fontSize(24) | |
fill(self.data.a) | |
text("Start", WIDTH / 2, HEIGHT / 2 - 96) | |
fill(self.data.b) | |
text("Highscores", WIDTH / 2, 96) | |
popMatrix() | |
popStyle() | |
end | |
function Menu:touched(touch) | |
local time = 0.25 | |
pushStyle() | |
font("Copperplate-Light") | |
fontSize(24) | |
local w, h = textSize("Start") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(HEIGHT / 2 - 96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.a == 0 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 128}) | |
self.tweened.a = 1 | |
end | |
else | |
if self.tweened.a == 1 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
self.tweened.a = 0 | |
state = 2 | |
end | |
end | |
else | |
if self.tweens.a ~= -1337 and self.tweened.a == 1 then | |
tween.stop(self.tweens.a) | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
end | |
self.tweened.a = 0 | |
end | |
local w, h = textSize("Highscores") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.b == 0 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 128}) | |
self.tweened.b = 1 | |
end | |
else | |
if self.tweened.b == 1 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
self.tweened.b = 0 | |
state = 4 | |
end | |
end | |
else | |
if self.tweens.b ~= -1337 and self.tweened.b == 1 then | |
tween.stop(self.tweens.b) | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
end | |
self.tweened.b = 0 | |
end | |
popStyle() | |
end | |
function Menu:keyboard(key) | |
end | |
--# Mushroom | |
Mushroom = class() | |
function Mushroom:init(game, x, y) | |
self.game = game | |
self.pos = vec2(x, y) | |
self.imgs = { | |
readImage("Platformer Art:Mushroom"), | |
readImage("Documents:DL-Asset-mushroom_red"), | |
} | |
self.img = self.imgs[math.random(1, #self.imgs)] | |
self.angle = 0 | |
self:calcAngle() | |
self.bounceTime = 0 | |
self.type = "mushroom" | |
end | |
function Mushroom:calcAngle() | |
if self.pos.x <= WIDTH / 2 then | |
self.angle = -90 | |
else | |
self.angle = 90 | |
end | |
end | |
function Mushroom:draw() | |
if math.abs(self.game.player.pos.y -self.pos.y) <= 70 and math.abs(self.game.player.pos.x -self.pos.x) <= 70 then | |
if self.bounceTime <= 30 then | |
self.bounceTime = self.bounceTime + 1 | |
self.game.player.motY = self.game.player.motY - 1.4 --1.52 | |
end | |
else | |
self.bounceTime = 0 | |
end | |
pushStyle() | |
pushMatrix() | |
translate(self.pos.x, self.pos.y) | |
rotate(self.angle) | |
sprite(self.img) | |
popMatrix() | |
popStyle() | |
end | |
--# Player | |
Player = class() | |
function Player:init(game, x, y) | |
self.game = game | |
self.pos = vec2(x, y) | |
self.motX = 2 | |
self.motY = 1 | |
self.move = false | |
self.poses = { | |
readImage("Platformer Art:Guy Standing"), | |
readImage("Platformer Art:Guy Look Right"), | |
readImage("Platformer Art:Guy Jump"), | |
readImage("Documents:DL-Asset-hurt"), | |
readImage("Documents:DL-Asset-walk01"), | |
readImage("Documents:DL-Asset-walk02"), | |
readImage("Documents:DL-Asset-walk03"), | |
readImage("Documents:DL-Asset-walk04"), | |
readImage("Documents:DL-Asset-walk05"), | |
readImage("Documents:DL-Asset-walk06"), | |
readImage("Documents:DL-Asset-walk07"), | |
readImage("Documents:DL-Asset-walk08"), | |
readImage("Documents:DL-Asset-walk09"), | |
readImage("Documents:DL-Asset-walk10"), | |
readImage("Documents:DL-Asset-walk11"), | |
} | |
self.pose = 5 | |
self.aestheticAngle = {a = 0} | |
self.tid = 0 | |
self.t = {x = 0, y = 0, lastX = 0, lastY = 0, deltaX = 0, deltaY = 0, state = ENDED, id = -1} | |
self:lookScared() | |
self:loopNextWalkImg() | |
self.won = false | |
self.dir = 1 | |
self.breakScared = false | |
self.breakWalk = false | |
self.onLedge = false | |
end | |
function Player:lookScared() | |
if not self.breakScared then | |
if self.pose == 3 then | |
self.pose = 4 | |
tween.delay(2, function() | |
if self.pose == 4 then | |
self.pose = 3 | |
end | |
end) | |
end | |
tween.delay(6 + math.random(0, 2), function() | |
self:lookScared() | |
end) | |
end | |
end | |
function Player:loopNextWalkImg() | |
if not self.breakWalk then | |
self:nextWalkImg() | |
tween.delay(0.1, function() | |
self:loopNextWalkImg() | |
end) | |
end | |
end | |
function Player:nextWalkImg() | |
if self.pose >= 5 then | |
self.pose = self.pose + 1 | |
end | |
if self.pose == 16 then | |
self.pose = 5 | |
end | |
end | |
function Player:draw() | |
if self.move and self.pos.y >= HEIGHT - 100 and not self.won then | |
self.won = true | |
game:win() | |
end | |
if self.t.id == self.tid and (self.t.state == BEGAN or self.t.state == MOVING) then | |
self.motX = 0.999 * self.motX + 0.001 * (self.t.x - self.pos.x) | |
end | |
if self.move then | |
if isRecording() then | |
if not self.onLedge then | |
self.motY = math.min(15, self.motY + 0.1) | |
self.pos.y = self.pos.y - self.motY | |
end | |
self.motX = math.max(-15, math.min(15, self.motX * 0.99)) | |
self.pos.x = self.pos.x + self.motX | |
else | |
if not self.onLedge then | |
self.motY = math.min(15, self.motY + 0.1) | |
self.pos.y = self.pos.y - self.motY * DeltaTime * 60 | |
end | |
self.motX = math.max(-15, math.min(15, self.motX * 0.99)) | |
self.pos.x = self.pos.x + self.motX * DeltaTime * 60 | |
end | |
self.pos.x = math.max(WIDTH * 0.2, math.min(WIDTH * 0.8, self.pos.x)) | |
if self.pos.x == WIDTH * 0.2 or self.pos.x == WIDTH * 0.8 then | |
self.motX = self.motX / math.abs(self.motX) * 0.01 | |
end | |
self.dir = self.motX / math.abs(self.motX) | |
end | |
self.game.offset.y = math.max(0, -self.pos.y + HEIGHT / 2) | |
pushStyle() | |
pushMatrix() | |
translate(self.pos.x, self.pos.y) | |
rotate(self.aestheticAngle.a) | |
sprite(self.poses[self.pose], 0, 0, self.dir * self.poses[self.pose].width, self.poses[self.pose].height) | |
popMatrix() | |
popStyle() | |
end | |
function Player:touched(touch) | |
if self.move then | |
if self.tid == 0 and touch.state == BEGAN then | |
self.tid = touch.id | |
self.t = touch | |
end | |
if touch.id == self.tid then | |
self.t = touch | |
end | |
if touch.id == self.tid and (touch.state == ENDED or touch.state == CANCELLED) then | |
self.tid = 0 | |
end | |
end | |
end | |
--# RenderBG | |
RenderBG = class() | |
function RenderBG:init(game) | |
self.game = game | |
self.grass = readImage("Documents:DL-Asset-grass_full") | |
self.dirt = readImage("Documents:DL-Asset-dirt") | |
self.stone = readImage("Documents:DL-Asset-stone") | |
self.lavaTop = readImage("Documents:DL-Asset-lava_top") | |
self.lava = readImage("Documents:DL-Asset-lava_full") | |
self.objImgs = { | |
readImage("Platformer Art:Bush"), | |
readImage("Platformer Art:Fence Broken"), | |
readImage("Platformer Art:Fence"), | |
readImage("Platformer Art:Mushroom"), | |
readImage("Documents:DL-Asset-rock"), | |
} | |
self.objs = {} | |
for i = 1, math.random(30, 40) do | |
self.objs[i] = {x = math.random(), side = math.random(0, 1), img = math.random(1, #self.objImgs)} | |
end | |
local gdist = 200 | |
self.bgMesh = mesh() | |
self.bgMesh.vertices = { | |
vec2(0, gdist), vec2(0, HEIGHT - gdist), vec2(WIDTH, HEIGHT - gdist), | |
vec2(0, gdist), vec2(WIDTH, gdist), vec2(WIDTH, HEIGHT - gdist), | |
} | |
self.bgMesh.colors = { | |
color(64), color(220, 255, 255), color(220, 255, 255), | |
color(64), color(64), color(220, 255, 255), | |
} | |
self.caveBg = mesh() | |
self.caveBg.vertices = { | |
vec2(0, -HEIGHT), vec2(0, gdist), vec2(WIDTH, gdist), | |
vec2(0, -HEIGHT), vec2(WIDTH, -HEIGHT), vec2(WIDTH, gdist), | |
} | |
self.caveBg.colors = { | |
color(64), color(64), color(64), | |
color(64), color(64), color(64), | |
} | |
end | |
function RenderBG:draw() | |
if self.game.offset.y < 200 then | |
background(220, 255, 255) | |
else | |
background(64) | |
end | |
--translate(0, -self.game.offset.y) | |
self.bgMesh:draw() | |
pushMatrix() | |
self.caveBg:draw() | |
popMatrix() | |
for x = 0, WIDTH * 0.2, 46 do | |
for y = math.floor(-self.game.offset.y / 46) * 46, math.floor(-self.game.offset.y / 46) * 46 + (HEIGHT - 145 + math.min(200, self.game.offset.y)), 46 do | |
if math.floor(y / 46) >= -8 then | |
sprite(self.dirt, x, y) | |
elseif math.floor(y / 46) == -256 then | |
sprite(self.lavaTop, x, y) | |
elseif math.floor(y / 46) <= -257 then | |
sprite(self.lava, x, y) | |
else | |
sprite(self.stone, x, y) | |
end | |
end | |
end | |
for x = 0, WIDTH * 0.2, 46 do | |
for y = math.floor(-self.game.offset.y / 46) * 46, math.floor(-self.game.offset.y / 46) * 46 + (HEIGHT - 145 + math.min(200, self.game.offset.y)), 46 do | |
if math.floor(y / 46) >= -8 then | |
sprite(self.dirt, WIDTH - x, y) | |
elseif math.floor(y / 46) == -256 then | |
sprite(self.lavaTop, WIDTH - x, y) | |
elseif math.floor(y / 46) <= -257 then | |
sprite(self.lava, WIDTH - x, y) | |
else | |
sprite(self.stone, WIDTH -x, y) | |
end | |
end | |
end | |
for x = 0, WIDTH, 46 do | |
for y = math.floor(-self.game.offset.y / 46) * 46, math.floor(-self.game.offset.y / 46) * 46 + (HEIGHT - 145 + math.min(200, self.game.offset.y)), 46 do | |
if math.floor(y / 46) == -256 then | |
sprite(self.lavaTop, x, y) | |
elseif math.floor(y / 46) <= -257 then | |
sprite(self.lava, x, y) | |
end | |
end | |
end | |
for x = 0, WIDTH * 0.2, 46 do | |
sprite(self.grass, x, HEIGHT - 170) | |
end | |
for x = 0, WIDTH * 0.2, 46 do | |
sprite(self.grass, WIDTH - x, HEIGHT - 170) | |
end | |
for k, v in ipairs(self.objs) do | |
sprite(self.objImgs[v.img], v.side * WIDTH * 0.85 + v.x * WIDTH * 0.15, HEIGHT - 100) | |
end | |
end | |
--# Replay | |
Replay = class() | |
function Replay:init() | |
self.bgSprites = { | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Documents:DL-Asset-rock"), | |
readImage("Documents:DL-Asset-mushroom_red"), | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Documents:DL-Asset-spring_pushed"), | |
readImage("Platformer Art:Guy Look Right"), | |
readImage("Documents:DL-Asset-grass_full"), | |
readImage("Platformer Art:Mushroom"), | |
} | |
self.offsets = { | |
50, | |
85, | |
85, | |
50, | |
75, | |
90, | |
50, | |
85, | |
} | |
self.angleOffset = 0 | |
self.data = {a = 0, b = 0} | |
self.tweened = {a = 0, b = 0} | |
self.tweens = {a = -1337, b = -1337} | |
end | |
function Replay:draw() | |
pushStyle() | |
pushMatrix() | |
background(255) | |
pushMatrix() | |
translate(WIDTH / 2, HEIGHT / 2 + 196) | |
rotate(self.angleOffset) | |
for k, v in ipairs(self.bgSprites) do | |
sprite(v, 0, self.offsets[k]) | |
rotate(360 / #self.bgSprites) | |
end | |
if isRecording() then | |
self.angleOffset = self.angleOffset + 0.5 | |
else | |
self.angleOffset = self.angleOffset + 0.5 * DeltaTime * 60 | |
end | |
popMatrix() | |
fill(0) | |
fontSize(48) | |
font("Copperplate-Light") | |
text("YOU WON", WIDTH / 2, HEIGHT / 2 + 96) | |
text("YOUR SCORE: " .. string.format("%18.0f", math.floor(states[2].score)), WIDTH / 2, HEIGHT / 2) | |
fontSize(24) | |
fill(self.data.a) | |
text("Replay", WIDTH / 2, HEIGHT / 2 - 96) | |
fill(self.data.b) | |
text("Highscores", WIDTH / 2, 96) | |
popMatrix() | |
popStyle() | |
end | |
function Replay:touched(touch) | |
local time = 0.25 | |
pushStyle() | |
font("Copperplate-Light") | |
fontSize(24) | |
local w, h = textSize("Replay") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(HEIGHT / 2 - 96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.a == 0 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 128}) | |
self.tweened.a = 1 | |
end | |
else | |
if self.tweened.a == 1 then | |
if self.tweens.a ~= -1337 then | |
tween.stop(self.tweens.a) | |
end | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
self.tweened.a = 0 | |
state = 2 | |
states[2].score = 0 | |
end | |
end | |
else | |
if self.tweens.a ~= -1337 and self.tweened.a == 1 then | |
tween.stop(self.tweens.a) | |
self.tweens.a = tween(time, self.data, {a = 0}) | |
end | |
self.tweened.a = 0 | |
end | |
local w, h = textSize("Highscores") | |
if math.abs(WIDTH / 2 - touch.x) <= w and math.abs(96 - touch.y) <= h then | |
if touch.state == BEGAN or touch.state == MOVING then | |
if self.tweened.b == 0 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 128}) | |
self.tweened.b = 1 | |
end | |
else | |
if self.tweened.b == 1 then | |
if self.tweens.b ~= -1337 then | |
tween.stop(self.tweens.b) | |
end | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
self.tweened.b = 0 | |
state = 4 | |
end | |
end | |
else | |
if self.tweens.b ~= -1337 and self.tweened.b == 1 then | |
tween.stop(self.tweens.b) | |
self.tweens.b = tween(time, self.data, {b = 0}) | |
end | |
self.tweened.b = 0 | |
end | |
popStyle() | |
end | |
function Replay:keyboard(key) | |
end | |
--# Spring | |
Spring = class() | |
function Spring:init(game, x, y) | |
self.game = game | |
self.pos = vec2(x, y) | |
self.imgs = { | |
readImage("Documents:DL-Asset-spring_pushed"), | |
readImage("Documents:DL-Asset-spring_popped"), | |
} | |
self.baseImg = readImage("Documents:DL-Asset-stone_ledge_left") | |
self.pose = 1 | |
self.img = self.imgs[self.pose] | |
self.dir = 1 | |
self:calcDir() | |
self.bounceTime = 0 | |
self.type = "spring" | |
end | |
function Spring:calcDir() | |
if self.pos.x <= WIDTH / 2 then | |
self.dir = 1 | |
else | |
self.dir = -1 | |
end | |
end | |
function Spring:draw() | |
if math.abs(self.game.player.pos.y -self.pos.y) <= 70 and math.abs(self.game.player.pos.x -self.pos.x) <= 70 then | |
if self.bounceTime <= 20 then | |
self.bounceTime = self.bounceTime + 1 | |
self.game.player.motY = self.game.player.motY - 2.55 --1.52 | |
self.pose = 2 | |
end | |
if self.game.player.pos.y < self.pos.y - 20 then | |
self.game.player.motY = -self.game.player.motY * 0.5 | |
self.game.player.pos.y = self.game.player.pos.y - 5 | |
self.pose = 1 | |
end | |
else | |
self.pose = 1 | |
self.bounceTime = 0 | |
end | |
pushStyle() | |
pushMatrix() | |
self.img = self.imgs[self.pose] | |
translate(self.pos.x, self.pos.y) | |
sprite(self.img) | |
translate(0, -70) | |
sprite(self.baseImg, 0, 0, self.dir * self.baseImg.width, self.baseImg.height) | |
popMatrix() | |
popStyle() | |
end | |
--# Util | |
function lineCount() | |
local lines = 0 | |
for k, v in ipairs(listProjectTabs()) do | |
for i in (readProjectTab(v) .. "\n"):gmatch("(.-)\n") do | |
lines = lines + 1 | |
end | |
end | |
print("Total lines of code: " .. string.format("%.f", lines)) | |
end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment