Skip to content

Instantly share code, notes, and snippets.

@SkyTheCoder
Last active December 19, 2015 16:49
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save SkyTheCoder/4bf470e3aa27a904fd7f to your computer and use it in GitHub Desktop.
Save SkyTheCoder/4bf470e3aa27a904fd7f to your computer and use it in GitHub Desktop.
Codea Project Gist Created with AutoGist
-- Expansion+
-- Use this function to perform your initial setup
function setup()
displayMode(FULLSCREEN_NO_BUTTONS)
supportedOrientations(LANDSCAPE_ANY)
gameState = 1
tax = 0.05 -- Percentage
stateData = {
-- Main menu data
{
playTint = color(255),
playSize = vec2(100, 60),
playPos = vec2(WIDTH / 2, 300),
exitTint = color(255),
},
-- In-game data
{
nextTint = color(255),
prevTint = color(255),
selectedTint = color(255),
exitTint = color(255),
saveTint = color(255),
loadTint = color(255),
plusTint = color(255),
minusTint = color(255),
page = 1,
saveID = 1,
},
}
-- Initialize world, and clear all objects.
worldData = {}
for y=1,7 do
table.insert(worldData, {})
for x=1,10 do
table.insert(worldData[y], 0)
end
end
worldData[6][2] = 1
data = stateData[gameState]
money = 50
debt = 0
selectedType = -1
images = {
-- 1
{
-- Image
readImage("Small World:Store"),
-- Price
100,
-- Income
5,
},
-- 2
{
-- Image
readImage("Small World:Store Medium"),
-- Price
200,
-- Income
15,
},
-- 3
{
-- Image
readImage("Small World:Store Large"),
-- Price
350,
-- Income
25,
},
-- 4
{
-- Image
readImage("Small World:Store Extra Large"),
-- Price
1500,
-- Income
50,
},
-- 5
{
-- Image
readImage("Small World:Mine"),
-- Price
1350,
-- Income
40,
},
-- 6
{
-- Image
readImage("Small World:Mine Medium"),
-- Price
2500,
-- Income
60,
},
-- 7
{
-- Image
readImage("Small World:Mine Large"),
-- Price
5000,
-- Income
75,
},
-- 8
{
-- Image
readImage("Small World:House White"),
-- Price
100,
-- Income
0,
},
-- 9
{
-- Image
readImage("Small World:House"),
-- Price
100,
-- Income
0,
},
-- 10
{
-- Image
readImage("Small World:Windmill"),
-- Price
6500,
-- Income
85,
},
-- 11
{
-- Image
readImage("Small World:Church"),
-- Price
8500,
-- Income
100,
-- Size
vec2(78, 115),
},
-- 12
{
-- Image
readImage("Small World:Court"),
-- Price
14500,
-- Income
150,
-- Size
vec2(78, 84),
},
-- 13
{
-- Image
readImage("Small World:Fountain"),
-- Price
150,
-- Income
0,
},
-- 14
{
-- Image
readImage("Small World:Tree Round"),
-- Price
25,
-- Income
0,
},
-- 15
{
-- Image
readImage("Small World:Tree 1"),
-- Price
50,
-- Income
0,
},
-- 16
{
-- Image
readImage("Small World:Tree 3"),
-- Price
100,
-- Income
0,
},
-- 17
{
-- Image
readImage("Small World:Bush"),
-- Price
50,
-- Income
0,
},
-- 18
{
-- Image
readImage("Small World:Flower 1"),
-- Price
15,
-- Income
0,
},
-- 19
{
-- Image
readImage("Small World:Tower"),
-- Price
1000,
-- Income
0,
-- Size
vec2(100, 100),
},
-- 20
{
-- Image
readImage("Small World:Observatory"),
-- Price
5000,
-- Income
75,
},
-- 21
{
-- Image
readImage("Small World:Watch Tower"),
-- Price
5000,
-- Income
75,
},
}
-- Building template
-- Size (Custom width/height) is optional, but you can include it if the sprite you want is too big.
--[[
-- ID
{
-- Image
readImage(),
-- Price
0,
-- Income
0,
-- Size
vec2(0, 0)
},
--]]
people = {}
oldTime = 0
taxTime = 0
taxTimeBetween = 15 -- Number of seconds between paying taxes
parameter.watch("1 / DeltaTime")
end
-- This function gets called once every frame
function draw()
data = stateData[gameState]
noSmooth()
textMode(CENTER)
-- This sets a dark background color
background(40, 40, 50)
-- This sets the line thickness
--strokeWidth(5)
noStroke()
-- Do your drawing here
if gameState == 1 then
pushStyle()
sprite("SpaceCute:Background", WIDTH / 2, HEIGHT / 2, WIDTH, HEIGHT)
font("HelveticaNeue-CondensedBlack")
fontSize(24)
fill(255)
text("Double-tap on a building\nto sell it for half the\nprice you paid for it.", 200, HEIGHT - 200)
text("Every fifteen seconds you\npay taxes. (five percent of\nthe cost of your buildings.)", WIDTH / 2, HEIGHT - 200)
text("Use the arrows to choose\na building, tap on it to select it,\nand tap on the grass to place it.", WIDTH - 200, HEIGHT - 200)
text("If you pay more taxes than the\nincome of your shops/mines, you\nwill lose money and get in debt.", 200, 200)
text(" Some buildings just look\n pretty and don't get income.\n Houses, for instance, spawn people.", WIDTH / 2, 200)
text(" The original game was\n made in under\n twenty-four hours!", WIDTH - 200, 200)
text("You start with\nfifty dollars,\nand a shop\nfor money.", 100, HEIGHT / 2)
text("Save up,\nand spend\nyour money\nwisely!", WIDTH - 100, HEIGHT / 2)
fontSize(48)
fill(data.playTint)
text("Play!", data.playPos.x, data.playPos.y)
local pw, ph = textSize("Play!")
stateData[gameState].playSize = vec2(pw, ph)
fontSize(124)
fill(255)
text("EXPANSION+", WIDTH / 2, 400)
popStyle()
tint(data.exitTint)
sprite("Cargo Bot:Command Right", WIDTH - 22, HEIGHT - 22)
noTint()
elseif gameState == 2 then
if oldTime ~= math.floor(ElapsedTime) then
payMoney()
for i=1,#images do
if data.selectedTint == color(255, 0, 0) then
data.selectedTint = color(255)
end
end
for i=1,#people do
local boundary = 100 -- The closest to the edge of the screen the person can go
local px, py = people[i][2].x, people[i][2].y
tween(1,
people[i][2],
{x = math.max(boundary, math.min(WIDTH - boundary, px + math.random(-100, 100))),
y = math.max(boundary, math.min(HEIGHT - 277 - boundary, py + math.random(-100, 100)))},
tween.easing.quadInOut)
end
oldTime = math.floor(ElapsedTime)
end
if taxTime + taxTimeBetween <= math.floor(ElapsedTime) then
taxTime = math.floor(ElapsedTime)
payTaxes()
end
pushStyle()
noStroke()
fill(63, 31, 15)
rect(0, HEIGHT - 176, WIDTH, 176)
stroke(127, 63, 31)
strokeWidth(10)
noFill()
rect(0, HEIGHT - 176, WIDTH, 176)
fill(255)
font("HelveticaNeue-CondensedBlack")
fontSize(24)
sprite("Small World:Treasure", 88, HEIGHT - 122, 125, 75)
if data.selectedTint == color(255, 0, 0) then
fill(data.selectedTint)
end
text("Income: $" .. string.gsub(string.format("%18.0f", getIncome()), " ", "") .. "/S", 88, HEIGHT - 22)
text("Money: $" .. string.gsub(string.format("%18.0f", money), " ", ""), 88, HEIGHT - 44)
text("Debt: $" .. string.gsub(string.format("%18.0f", debt), " ", ""), 88, HEIGHT - 66)
local taxes = 0
for k,row in ipairs(worldData) do
for v,col in ipairs(row) do
if col ~= 0 then
taxes = taxes + images[col][2]
end
end
end
taxes = tax * taxes
text("Taxes: $" .. string.gsub(string.format("%18.0f", taxes), " ", "") .. "/" .. taxTimeBetween .. "S", 88, HEIGHT - 88)
fill(255)
tint(data.prevTint)
sprite("Cargo Bot:Command Left", (WIDTH / 2) - 100, HEIGHT - 122)
noTint()
tint(data.nextTint)
sprite("Cargo Bot:Command Right", (WIDTH / 2) + 100, HEIGHT - 122)
noTint()
tint(data.selectedTint)
if images[data.page][4] ~= nil then
sprite(images[data.page][1], WIDTH / 2, HEIGHT - 122, images[data.page][4].x, images[data.page][4].y)
else
sprite(images[data.page][1], WIDTH / 2, HEIGHT - 122)
end
noTint()
tint(data.exitTint)
sprite("Cargo Bot:Command Right", WIDTH - 22, HEIGHT - 22)
noTint()
tint(data.loadTint)
sprite("Cargo Bot:Condition Red", WIDTH - 88, HEIGHT - 22)
fontSize(12)
text("Load", WIDTH - 88, HEIGHT - 21)
fontSize(24)
noTint()
tint(data.saveTint)
sprite("Cargo Bot:Condition Green", WIDTH - 166, HEIGHT - 22)
fontSize(12)
text("Save", WIDTH - 166, HEIGHT - 22)
fontSize(24)
noTint()
tint(data.minusTint)
sprite("Cargo Bot:Command Left", WIDTH - 188, HEIGHT - 88)
noTint()
tint(data.plusTint)
sprite("Cargo Bot:Command Right", WIDTH - 66, HEIGHT - 88)
noTint()
fill(math.min(data.minusTint.r, data.plusTint.r))
text(tostring(data.saveID), WIDTH - 127, HEIGHT - 88)
fill(255)
fill(data.selectedTint)
text("Price: $" .. images[data.page][2], WIDTH / 2, HEIGHT - 44)
text("Income: $" .. images[data.page][3] .. "/S", WIDTH / 2, HEIGHT - 66)
fill(255)
text(data.page .. "/" .. #images, WIDTH / 2, HEIGHT - 22)
-- Draw grass
for x=53,WIDTH,102 do
for y=HEIGHT-(36+176),1,-85 do
sprite("Planet Cute:Grass Block", x, y, 108, 176)
end
end
-- Draw world
for y=7,1,-1 do
for x=1,10 do
local id = worldData[y][x]
if id ~= 0 then
pushMatrix()
resetMatrix()
local px, py = ((x / 10) * WIDTH) - 50, ((y / 9) * HEIGHT) - 25
local sid = math.max(1, math.min(#images, id))
if sid == 5 or sid == 6 or sid == 7 or sid == 10 then
local offset = 22
translate(px + offset, py + offset + math.sin(5 * ElapsedTime))
rotate(math.cos(5 * ElapsedTime))
px, py = -offset, -offset
end
if images[sid][4] ~= nil then
sprite(images[sid][1], px, py, images[sid][4].x, images[sid][4].y)
else
sprite(images[sid][1], px, py)
end
popMatrix()
end
end
end
for k,v in ipairs(people) do
local gender = v[1]
local pos = v[2]
if gender == 1 then
sprite("Planet Cute:Character Boy", pos.x, pos.y, 50, 85)
end
if gender == 2 then
sprite("Planet Cute:Character Pink Girl", pos.x, pos.y, 50, 85)
end
end
popStyle()
--money = money + 1
--text(tostring(getTilePressed(CurrentTouch.x, CurrentTouch.y)), WIDTH / 2, HEIGHT / 2)
end
end
function touched(touch)
if gameState == 1 then
if inRange(touch.x, touch.y, data.playPos.x, data.playPos.y, data.playSize.x, data.playSize.y) then
if touch.state == BEGAN or touch.state == MOVING then
stateData[gameState].playTint = color(127)
elseif touch.state == ENDED then
stateData[gameState].playTint = color(255)
oldTime = math.floor(ElapsedTime)
taxTime = math.floor(ElapsedTime)
gameState = 2
end
else
stateData[gameState].playTint = color(255)
end
if touch.state == BEGAN or touch.state == MOVING then
if inRange(touch.x, touch.y, WIDTH - 22, HEIGHT - 22, 50, 50) then
stateData[gameState].exitTint = color(127)
else
stateData[gameState].exitTint = color(255)
end
end
if touch.state == ENDED then
if inRange(touch.x, touch.y, WIDTH - 22, HEIGHT - 22, 50, 50) then
stateData[gameState].exitTint = color(255)
close()
end
end
elseif gameState == 2 then
if touch.state == ENDED then
if touch.y < HEIGHT - 176 then
local pos = getTilePressed(touch.x, touch.y)
if selectedType == -1 and touch.tapCount == 2 and worldData[pos.y][pos.x] ~= 0 then
local id = worldData[pos.y][pos.x]
if id == 8 or id == 9 then
table.remove(people, #people)
end
giveMoney(images[worldData[pos.y][pos.x]][2] / 2)
worldData[pos.y][pos.x] = 0
end
if worldData[pos.y][pos.x] == 0 then
if selectedType ~= -1 then
worldData[pos.y][pos.x] = selectedType
if selectedType == 8 or selectedType == 9 then
table.insert(people, {math.random(1, 2), {x = (pos.x / 10) * WIDTH, y = (pos.y / 7) * (HEIGHT - 176)}})
end
selectedType = -1
end
end
else
if inRange(touch.x, touch.y, WIDTH / 2 - 100, HEIGHT - 122, 50, 50) then
stateData[gameState].prevTint = color(255)
if data.page > 1 then
stateData[gameState].page = data.page - 1
end
end
if inRange(touch.x, touch.y, WIDTH / 2 + 100, HEIGHT - 122, 50, 50) then
stateData[gameState].nextTint = color(255)
if data.page < #images then
stateData[gameState].page = data.page + 1
end
end
if inRange(touch.x, touch.y, WIDTH / 2, HEIGHT - 122, 100, 100) then
if money >= images[data.page][2] and selectedType == -1 then
stateData[gameState].selectedTint = color(255)
takeMoney(images[data.page][2])
selectedType = data.page
else
stateData[gameState].selectedTint = color(255, 0, 0)
end
end
if inRange(touch.x, touch.y, WIDTH - 22, HEIGHT - 22, 50, 50) then
stateData[gameState].exitTint = color(255)
gameState = 1
end
local name = "Expansion+"
if inRange(touch.x, touch.y, WIDTH - 88, HEIGHT - 22, 50, 50) then
if readGlobalData(name .. ".world" .. tostring(data.saveID)) ~= nil then
worldData = loadstring(readGlobalData(name .. ".world" .. tostring(data.saveID)))()
money = readGlobalData(name .. ".money" .. tostring(data.saveID))
debt = readGlobalData(name .. ".debt" .. tostring(data.saveID))
--print(readGlobalData(name .. ".world"))
--print(compressTable({"Test 1", {2}}))
--displayMode(STANDARD)
local c = #people
for i=1,c do
table.remove(people)
end
for py,row in ipairs(worldData) do
for px,col in ipairs(row) do
if col == 8 or col == 9 then
table.insert(people, {math.random(1, 2), {x = (px / 10) * WIDTH, y = (py / 7) * (HEIGHT - 176)}})
end
end
end
end
stateData[gameState].loadTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH - 166, HEIGHT - 22, 50, 50) then
stateData[gameState].saveTint = color(255)
saveGlobalData(name .. ".world" .. tostring(data.saveID), compressTable(worldData))
saveGlobalData(name .. ".money" .. tostring(data.saveID), money)
saveGlobalData(name .. ".debt" .. tostring(data.saveID), debt)
end
if inRange(touch.x, touch.y, WIDTH - 188, HEIGHT - 88, 50, 50) then
stateData[gameState].minusTint = color(255)
stateData[gameState].saveID = data.saveID - 1
end
if inRange(touch.x, touch.y, WIDTH - 66, HEIGHT - 88, 50, 50) then
stateData[gameState].plusTint = color(255)
stateData[gameState].saveID = data.saveID + 1
end
end
end
if touch.state == BEGAN or touch.state == MOVING then
if inRange(touch.x, touch.y, WIDTH / 2 - 100, HEIGHT - 122, 50, 50) then
stateData[gameState].prevTint = color(127)
else
stateData[gameState].prevTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH / 2 + 100, HEIGHT - 122, 50, 50) then
stateData[gameState].nextTint = color(127)
else
stateData[gameState].nextTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH / 2, HEIGHT - 122, 100, 100) then
stateData[gameState].selectedTint = color(127)
else
stateData[gameState].selectedTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH - 22, HEIGHT - 22, 50, 50) then
stateData[gameState].exitTint = color(127)
else
stateData[gameState].exitTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH - 88, HEIGHT - 22, 50, 50) then
stateData[gameState].loadTint = color(127)
else
stateData[gameState].loadTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH - 166, HEIGHT - 22, 50, 50) then
stateData[gameState].saveTint = color(127)
else
stateData[gameState].saveTint = color(255)
end
if inRange(touch.x, touch.y, WIDTH - 188, HEIGHT - 88, 50, 50) then
stateData[gameState].minusTint = color(127)
else
stateData[gameState].minusTnt = color(255)
end
if inRange(touch.x, touch.y, WIDTH - 66, HEIGHT - 88, 50, 50) then
stateData[gameState].plusTint = color(127)
else
stateData[gameState].plusTint = color(255)
end
end
end
end
function compressTable(table)
compressed = "return "
searchTable(table)
return compressed --string.gsub(compressed "{, ", "{")
end
function compressValue(value)
if type(value) == "string" then
return string.format("%q", value)
else
return tostring(value)
end
end
function searchTable(table)
if compressed == "return " or compressed == "return {" or string.endsWith(compressed, "{") then
compressed = compressed .. "{"
else
compressed = compressed .. ", {"
end
for k,v in ipairs(table) do
if type(v) == "table" then
searchTable(v)
else
if string.endsWith(compressed, "{") then
compressed = compressed .. compressValue(v)
else
compressed = compressed .. ", " .. compressValue(v)
end
end
end
compressed = compressed .. "}"
end
function string.endsWith(s, pattern)
return not (not string.find(s, pattern .. "$"))
end
function payMoney()
giveMoney(getIncome())
end
function getIncome()
local income = 0
for k,row in ipairs(worldData) do
for v,col in ipairs(row) do
if col ~= 0 then
income = income + images[col][3]
end
end
end
return income
end
function payTaxes()
local amount = 0
for k,row in ipairs(worldData) do
for v,col in ipairs(row) do
if col ~= 0 then
amount = amount + images[col][2]
end
end
end
takeMoney(tax * amount)
end
function takeMoney(amount)
money = money - amount
if money < 0 then
debt = math.abs(money)
money = 0
end
end
function giveMoney(amount)
if debt > 0 then
debt = debt - amount
if debt < 0 then
money = math.abs(debt)
debt = 0
end
else
money = money + amount
end
end
function getTilePressed(x, y)
return vec2(math.floor(((x / WIDTH) * 10) + 1), math.floor(((y / (HEIGHT-176)) * 7) + 1))
end
function inRange(ax, ay, bx, by, bw, bh)
return ax > bx - (bw / 2) and ay > by - (bh / 2) and ax < bx + (bw / 2) and ay < by + (bh / 2)
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment