Rocket-Bytes/Source/Editor.lua
2022-07-16 19:37:12 -06:00

526 lines
No EOL
18 KiB
Lua

local gfx <const> = playdate.graphics
local prevtext = ""
local levelname = nil
local inverted = false
local tileTable <const> = gfx.imagetable.new("gfx/tiles")
local tilemapEditor = gfx.tilemap.new()
tilemapEditor:setImageTable(tileTable)
local tiles = {}
local sawblades = {}
local spins = {}
tilemapEditor:setSize(1000,1000)
local imgtiles = gfx.sprite.new(tilemapEditor)
local w, h = imgtiles:getSize()
imgtiles:moveTo(w/2,h/2)
local bool2int = {[true]=1,[false]=0}
local toolTipButton
local altClrButton
local pos1 = {x,y}
local editor = "main"
local editorSongs = {"song1","song2","song5", "song6", "song7", "song8"}
local selSong = "song2"
local songIndexSel = 10
local imgFloppy = gfx.imagetable.new("gfx/floppyT")
local imgAdd = gfx.image.new("gfx/add")
local imgMus = gfx.image.new("gfx/music")
local imgLine = gfx.image.new("gfx/line")
local imgSpin = gfx.image.new("gfx/spin")
local imgCursor = gfx.image.new("gfx/cursor2")
local imgCant = gfx.image.new("gfx/nothing")
local imgSquare = gfx.image.new("gfx/square")
local imgRocket = gfx.image.new("gfx/start")
local imgExit = gfx.image.new("gfx/exit")
local imgEye = gfx.image.new("gfx/eye")
local imgPlayer = gfx.image.new("gfx/rocket")
local imgPlayerExit = gfx.image.new("gfx/bigrocket")
local imgExitMen = gfx.image.new("gfx/leave")
local imgSaw = gfx.imagetable.new("gfx/sawblades")
local imgTarget = gfx.image.new("gfx/target")
local imgGrid = gfx.image.new("gfx/grid")
local imgWarn = gfx.image.new("gfx/warningsign")
assert(imgFloppy)
assert(imgAdd)
assert(imgMus)
assert(imgLine)
assert(imgSpin)
assert(imgCursor)
assert(imgSquare)
assert(imgRocket)
assert(imgEye)
assert(imgPlayer)
assert(imgPlayerExit)
assert(imgSaw)
assert(imgTarget)
assert(imgGrid)
assert(imgWarn)
local animFloppy = gfx.animation.loop.new(100, imgFloppy)
local saveTime = 0
local playerPos = {x=1562,y=1564}
local exitPos = {x = 1616, y = 1536}
local position = {x=100,y=100}
local positionLerp = {x=0,y=0}
local powers = {}
function newProject()
mode = "newproj"
playdate.keyboard.show("NEW LEVEL")
end
local createNewFont <const> = gfx.font.new("gfx/bigVisibleSpaces")
function updateNewproj()
gfx.clear()
processStars(-10,-10)
gfx.drawText("LEVEL NAME:", 35, 100)
gfx.drawTextInRect(playdate.keyboard.text:upper(),0,130, 210, 80,0,nil,kTextAlignment.center,createNewFont)
end
function editLoadName(name)
song:stop()
mode = "editor"
local data = json.decodeFile("levels/"..name)
powers = data.fuel
sawblades = data.saws
spins = data.rotators
playerPos = {x = data.rocket.x, y = data.rocket.y}
exitPos = {x = data.bigrocket.x, y = data.bigrocket.y}
position = {x = (data.rocket.x + 6) / 16, y = (data.rocket.y + 4)/16}
levelname = name:match("(.+)%..+$")
inverted = data.inverted
playdate.display.setInverted(data.inverted)
saveTime = 0
-- loading tiles
for tile = 1, #data.tiles, 1 do
tilemapEditor:setTileAtPosition(data.tiles[tile].x,data.tiles[tile].y,data.tiles[tile].t)
tiles[tile] = {x=data.tiles[tile].x,y=data.tiles[tile].y,t=data.tiles[tile].t}
end
altClrButton = playdate.getSystemMenu():addCheckmarkMenuItem("alt colours",inverted, function(value)
playdate.display.setInverted(value)
inverted = value
end)
toolTipButton = playdate.getSystemMenu():addMenuItem("save", function()
editSave()
end)
imgtiles:add()
end
function playdate.keyboard.keyboardWillHideCallback(ok)
if ok == false then
page = 0
playdate.wait(0.3)
editLoad()
elseif #playdate.keyboard.text:upper() > 0 then
song:stop()
mode = "editor"
position = {x=89,y=93}
playerPos = {x=1562,y=1564}
exitPos = {x = 1616, y = 1536}
inverted = false
playdate.display.setInverted(false)
saveTime = 0
song:stop()
playdate.getSystemMenu():addCheckmarkMenuItem("alt colours",false, function(value)
playdate.display.setInverted(value)
inverted = value
end)
playdate.getSystemMenu():addMenuItem("save",false, function()
editSave()
end)
levelname = playdate.keyboard.text:upper()
imgtiles:add()
else
page = 0
playdate.wait(0.3)
editLoad()
end
end
function playdate.keyboard.textChangedCallback()
local newTex = playdate.keyboard.text:gsub("/", ""):gsub("\\", ""):gsub("|", ""):gsub(":", ""):gsub("*", ""):gsub("?", ""):gsub('"', ""):gsub("<", ""):gsub(">", "")
if #newTex > 24 then
newTex = prevtext
end
playdate.keyboard.text = newTex
prevtext = newTex
end
local tileIndex = 0.0
local curY = math.floor( tileIndex ) * 28 + 3
local curYlerp = -32
function editSave()
playdate.datastore.delete("levels/"..levelname..".json")
saveTime = 5
playdate.datastore.write({song=selSong, tiles = tiles, inverted = inverted, rocket=playerPos, bigrocket=exitPos, fuel = powers,saws=sawblades,rotators=spins},"levels/"..levelname)
end
local traveltime = 1
local armamount = 1
local armlength = 1
function editUpdate()
--print(math.floor( tileIndex ) )
local change, aChange = playdate.getCrankChange()
tileIndex += change * 0.01
if editor == "main" then
if tileIndex > 7.9 then tileIndex = 0 end
if tileIndex < 0 then tileIndex = 7.9 end
curY = math.floor( tileIndex ) * 28 +7
elseif editor == "tiles" then
if tileIndex < 0 then tileIndex = #tileTable-.1 end
if tileIndex > #tileTable then tileIndex = 0 end
curY = (math.floor( tileIndex ) % 8) * 28 +7
elseif editor == "music" then
if tileIndex > #editorSongs - 0.1 then tileIndex = 0 end
if tileIndex < 0 then tileIndex = #editorSongs - 0.1 end
curY = math.floor( tileIndex ) * 28 +7
if songIndexSel ~= math.floor(tileIndex) then
songIndexSel = math.floor(tileIndex)
song:stop()
song:load("sfx/"..editorSongs[songIndexSel+1])
song:play()
end
elseif editor == "pos2Saw" then
traveltime += change * 0.002
if traveltime < 0.2 then traveltime = 0.2 end
traveltime = tonumber(string.format("%.2f", traveltime))
elseif editor == "pos2Spin" then
traveltime += change * 0.001
traveltime = tonumber(string.format("%.2f", traveltime))
end
curYlerp = playdate.math.lerp(curYlerp, curY, 0.4)
positionLerp.x = playdate.math.lerp(positionLerp.x, position.x * 16, 0.5)
positionLerp.y = playdate.math.lerp(positionLerp.y, position.y * 16, 0.5)
if playdate.buttonJustPressed(playdate.kButtonA) then
if editor == "pos2Saw" then
sawblades[#sawblades+1] = {start={x=pos1.x,y=pos1.y},ends = {x=(position.x + 11) * 16,y=(position.y + 7) * 16}, speed = traveltime}
editor = "main"
tileIndex = 2
elseif editor == "music" then
selSong = editorSongs[math.floor(tileIndex) + 1]
editor = "main"
song:stop()
song:load("sfx/song1")
tileIndex = 6
songIndexSel = #editorSongs + 1
elseif editor == "pos2Spin" then
spins[#spins+1] = {middle=true,x=pos1.x,y=pos1.y,speed=traveltime,arms=armamount,armlen=armlength}
editor = "main"
tileIndex = 3
printTable(spins[#spins])
elseif editor == "tiles" then
if math.floor( tileIndex ) == 0 then
editor = "main"
else
tilemapEditor:setTileAtPosition(position.x+12,position.y+8,math.floor( tileIndex ) + 1)
tiles[#tiles+1] = {x=position.x + 12, y=position.y + 8, t=math.floor( tileIndex ) + 1}
imgtiles = gfx.sprite.new(tilemapEditor)
end
elseif editor == "main" then
if math.floor( tileIndex ) == 0 then
--[[
tilemapEditor:setTileAtPosition(position.x+12,position.y+8,2)
tiles[#tiles+1] = {x=position.x + 12, y=position.y + 8, t=2}
imgtiles = gfx.sprite.new(tilemapEditor)
]]
editor = "tiles"
elseif math.floor(tileIndex) == 1 then
powers[#powers+1] = {x=((position.x + 11) * 16)-7, y=((position.y + 7) * 16)-5}
elseif math.floor(tileIndex) == 2 then
traveltime = 1
pos1.x,pos1.y=((position.x + 11) * 16), ((position.y + 7) * 16)
editor = "pos2Saw"
elseif math.floor( tileIndex ) == 3 then
traveltime = .1
armamount = 1
armlength = 1
pos1.x,pos1.y=((position.x + 11) * 16), ((position.y + 7) * 16)
editor = "pos2Spin"
elseif math.floor(tileIndex) == 4 then
playerPos = {x = ((position.x + 11) * 16) - 6, y = ((position.y + 7) * 16) - 4}
elseif math.floor(tileIndex) == 5 then
exitPos = {x = (position.x + 11) * 16, y = (position.y + 7) * 16}
elseif math.floor(tileIndex) == 6 then
editor = "music"
elseif math.floor(tileIndex) == 7 then
editor = "view"
end
end
end
if playdate.buttonJustPressed(playdate.kButtonB) then
if editor == "tiles" then
tilemapEditor:setTileAtPosition(position.x+12,position.y+8,0)
for tile = 1, #tiles, 1 do
if tiles[tile].x == position.x + 12 and tiles[tile].y == position.y+8 then
table.remove(tiles,tile)
break
end
end
elseif editor == "pos2Saw" then
tileIndex = 2
editor = "main"
elseif editor == "pos2Spin" then
tileIndex = 3
editor = "main"
elseif editor == "main" then
--[[if math.floor( tileIndex ) == 0 then
tilemapEditor:setTileAtPosition(position.x+12,position.y+8,0)
for tile = 1, #tiles, 1 do
if tiles[tile].x == position.x + 12 and tiles[tile].y == position.y+8 then
table.remove(tiles,tile)
break
end
end
imgtiles = gfx.sprite.new(tilemapEditor)]]
if math.floor(tileIndex) == 1 then
for power = 1, #powers, 1 do
if powers[power].x == ((position.x + 11) * 16)-7 and powers[power].y == ((position.y + 7) * 16)-5 then
table.remove(powers,power)
break
end
end
elseif math.floor( tileIndex ) == 2 then
for saw= 1, #sawblades, 1 do
if sawblades[saw].start.x == (position.x + 11) * 16 and sawblades[saw].start.y == (position.y + 7) * 16 then
table.remove(sawblades, saw)
break
end
end
elseif math.floor( tileIndex ) == 3 then
for saw= 1, #spins, 1 do
if spins[saw].x == (position.x + 11) * 16 and spins[saw].y == (position.y + 7) * 16 then
table.remove(spins, saw)
break
end
end
end
elseif editor == "view" then
editor = "main"
tileIndex = 7.5
end
end
if playdate.buttonJustPressed(playdate.kButtonLeft) then
if editor ~= "pos2Spin" then
position.x -= 1
else
armamount-=1
if armamount < 1 then armamount = 1 end
end
elseif playdate.buttonJustPressed(playdate.kButtonRight) then
if editor ~= "pos2Spin" then
position.x += 1
else
armamount+=1
end
end
if playdate.buttonJustPressed(playdate.kButtonUp) then
if editor ~= "pos2Spin" then
position.y -= 1
else
armlength += 1
end
elseif playdate.buttonJustPressed(playdate.kButtonDown) then
if editor ~= "pos2Spin" then
position.y += 1
else
armlength-=1
if armlength < 1 then armlength = 1 end
end
end
if position.x + 11 < 0 then position.x = -11 end
if position.y + 7 < 0 then position.y = -7 end
gfx.clear()
-- draw map
gfx.setDrawOffset(-positionLerp.x, -positionLerp.y)
imgtiles:update()
imgPlayerExit:draw(exitPos.x, exitPos.y)
imgPlayer:draw(playerPos.x,playerPos.y)
for saw = 1, #sawblades, 1 do
local b = sawblades[saw]
imgSaw[1]:draw(b.start.x,b.start.y)
imgTarget:draw(b.ends.x,b.ends.y)
if editor == "main" and math.floor( tileIndex ) == 2 then
playdate.graphics.setLineWidth(2)
gfx.drawLine(b.start.x+8,b.start.y+8,b.ends.x+8,b.ends.y+8)
gfx.drawText(b.speed,b.start.x+8 - (gfx.getTextSize(b.speed)/2),b.start.y-16)
end
end
for saw = 1, #spins, 1 do
local spin = spins[saw]
imgSaw[2]:draw(spin.x,spin.y)
for arm = 1, spin.arms do
for blade = 1, spin.armlen do
local degrees = 360 / spin.arms * arm
local position = {x=math.sin(math.rad(degrees)) * 20 * blade,y=math.cos(math.rad(degrees)) * 20 * blade}
imgSaw[2]:draw(spin.x+position.x,spin.y+position.y)
end
end
--[[ for spinner = 1, #spinblades, 1 do
for arm = 1, #spinblades[spinner].arms do
for blade = 1, #spinblades[spinner].arms[arm] do
spinblades[spinner].time += spinblades[spinner].speed
local degrees = (360 / #spinblades[spinner].arms * arm + spinblades[spinner].time)
if degrees % 360 == 0 then spinblades[spinner].time = 0 end
local position = {x=math.sin(math.rad(degrees)) * 20 * blade,y=math.cos(math.rad(degrees)) * 20 * blade}
spinblades[spinner].arms[arm][blade]:setImage(loopSaws:image())
spinblades[spinner].arms[arm][blade]:moveTo(spinblades[spinner].mid.x + position.x, spinblades[spinner].mid.y + position.y)
end
end
end]]
if editor == "main" and math.floor( tileIndex ) == 3 then
gfx.drawText(spin.speed,spin.x+8 - (gfx.getTextSize(spin.speed)/2),spin.y-16)
end
end
for power = 1, #powers, 1 do
imgSquare:draw(powers[power].x,powers[power].y)
end
if editor ~= "view" then
imgGrid:drawTiled((position.x-2)*16,(position.y-2)*16,416,288)
imgCursor:draw((position.x + 11) * 16, (position.y + 7) * 16)
end
--[[
gfx.setColor(playdate.graphics.kColorXOR)
gfx.fillRect(((position.x + 11) * 16) + 3, ((position.y + 7) * 16) + 3,10,10)
]]
if position.y < 1 then
imgCant:drawTiled((position.x-1) * 16,-112,400,112)
end
if position.x < 1 then
imgCant:drawTiled(-176,(position.y-1) * 16,176,272)
end
if editor == "pos2Saw" then
imgSaw[1]:draw(pos1.x,pos1.y)
end
-- draw ui/
if editor ~= "view" then
gfx.setLineWidth(5)
gfx.setDrawOffset(0,0)
gfx.setColor(gfx.kColorBlack)
gfx.fillRect(362,0,400,240)
gfx.setColor(gfx.kColorWhite)
gfx.drawLine(360,0,360,240)
-- draw changes
if editor == "tiles" then
gfx.drawText("A TO PLACE \nB TO DELETE",0,0)
local ind = math.floor( tileIndex / 8 ) * 8
if tileIndex < 8 then imgExitMen:draw(366,8) else tileTable[1+ind]:draw(373,13) end
tileTable[2+ind]:draw(373,41)
tileTable[3+ind]:draw(373,69)
tileTable[4+ind]:draw(373,97)
tileTable[5+ind]:draw(373,125)
tileTable[6+ind]:draw(373,153)
tileTable[7+ind]:draw(373,181)
tileTable[8+ind]:draw(373,209)
elseif editor == "music" then
for i = 1, #editorSongs do
gfx.drawText(i,374,12+(28*(i-1)))
end
elseif editor == "pos2Saw" then
gfx.drawText("SELECT TARGET POSITION \nTRAVEL TIME: "..traveltime.."S",0,0)
elseif editor == "pos2Spin" then
gfx.drawText("< "..armamount.." > ARMS\nV "..armlength.." ^ BLADES PER ARM\nROTATION SPEED: "..traveltime,0,0)
elseif editor == "main" then
imgMus:draw(366, 176)
imgAdd:draw(366,8)
imgLine:draw(366,64)
imgSpin:draw(366,92)
imgSquare:draw(366,36)
imgRocket:draw(366, 120)
imgExit:draw(366,148)
imgEye:draw(366,204)
if math.floor( tileIndex ) == 0 then
gfx.drawText("TILES",0,0)
elseif math.floor( tileIndex ) == 1 then
gfx.drawText("POWER",0,0)
elseif math.floor( tileIndex ) == 2 then
gfx.drawText("MOVERS",0,0)
elseif math.floor( tileIndex ) == 3 then
gfx.drawText("SPINNERS",0,0)
imgWarn:draw(0,18)
gfx.drawText("VERY LAGGY",18,18)
elseif math.floor( tileIndex ) == 4 then
gfx.drawText("PLAYER",0,0)
elseif math.floor( tileIndex ) == 5 then
gfx.drawText("EXIT",0,0)
elseif math.floor( tileIndex ) == 6 then
gfx.drawText("MUSIC",0,0)
elseif math.floor( tileIndex ) == 7 then
gfx.drawText("VIEW",0,0)
end
end
gfx.setColor(playdate.graphics.kColorXOR)
gfx.fillRect(365,curYlerp,33,28)
end
if saveTime > 0 then
saveTime -= 0.1
animFloppy:draw(2,210)
end
end
function editClose()
for tile = 1, #tiles, 1 do
tilemapEditor:setTileAtPosition(tiles[tile].x,tiles[tile].y,0)
end
tiles = {}
powers = {}
sawblades = {}
spins = {}
editor = "main"
tileIndex = 0
playdate.display.setInverted(false)
imgtiles = gfx.sprite.new(tilemapEditor)
imgtiles:remove()
if #playdate.getSystemMenu():getMenuItems() > 1 then
playdate.getSystemMenu():removeMenuItem(playdate.getSystemMenu():getMenuItems()[3])
playdate.getSystemMenu():removeMenuItem(playdate.getSystemMenu():getMenuItems()[2])
end
end