return function() local state = {} local dataFolder = love.filesystem.getSaveDirectory() local files = require("modules.files") local json = require("modules.json") local logging = require("modules.logging") local charValues = require("playableCharValues.playables") local playables = charValues.playables local playableOffsets = charValues.offsets local playableFlips = charValues.flips curChar = playables[1] --this needs to be global local curCharIndex = 1 local songs = require(string.format("charts.songs-%s", curChar)) local unparsedData = files.read_file(dataFolder .. "/Data.json") local data = unparsedData and json.parse(unparsedData) or { songs = { bf = {} } } local icons = {} local function setupIcons() for index, icon in next, icons do icon:Destroy() end for index, song in next, songs do local icon = song.icon if not icon then goto evilgoto end local spriteicon = Sprite(string.format("sprites/freeplay/icons/%s.png", icon), string.format("sprites/freeplay/icons/%s.json", icon)) spriteicon:PlayAnimation("idle", .005, false) spriteicon.frame = 1 spriteicon.layer = 10 icons[song.name] = spriteicon ::evilgoto:: end end local flip = false local lastChange = 0 local startedPlaying = 0 local start = false local curSong = songs[1] local curIndex = 1 local evilCurIndex = 1 local curDiffList = songs[1].difficulties local bfAtlas = love.animate.newTextureAtlas() local picoAtlas local curDiff = songs[1].difficulties[1] local curDiffInd = 1 local diffIMG local charIcon local iconNum = math.random(1, 3) local curState = nil local stateLoaded = false local pressed = { false, false, false } local bg local logo local gf local charSwapSND = love.audio.newSource("sounds/CS_select.ogg", "stream") charSwapSND:setVolume(0.25) local left local arrow local function setup() if not freaky:isPlaying() then freaky:play() end start = false bg = Image("images/menuBG.png", 0) bg.ui = false bg.layer = -10 -- NO MORE GF left = Image("images/MenuLeft.png") left.layer = 0 left.resize = Vector2(2, 1) arrow = Sprite( string.format("sprites/freeplay/freeplaySelector-%s.png", curChar), string.format("sprites/freeplay/freeplaySelector-%s.json", curChar) ) arrow.position.y = 330 arrow.position.x = 20 arrow.layer = 1 arrow.resize = Vector2(.5, .5) arrow.flipX = true arrow:PlayAnimation("arrow pointer loop", 24, true) -- render.preLoad( -- "sprites/freeplay/freeplaySelector_pico.png", -- "sprites/freeplay/freeplaySelector.json" -- ) diffIMG = Sprite("images/diff/diffList.png", "images/diff/diffList.json") --look there was a different plan going in diffIMG:PlayAnimation(curDiff, 24, false) diffIMG.position = Vector2(400, 640) diffIMG.layer = 2 charIcon = Sprite("sprites/menu/charIcons.png", "sprites/menu/charIcons.json") charIcon:PlayAnimation(curChar .. iconNum, 24, false) charIcon.position = Vector2(350, 200) charIcon.resize = Vector2(0.25, 0.25) --this doesnt work and idk why charIcon.layer = 2 --since they won't overlap this is ok i think bfAtlas = love.animate.newTextureAtlas() bfAtlas:load(string.format("sprites/charSelect/%sChill", curChar)) bfAtlas:play(string.format("%s cs idle", curChar)) setupIcons() end local function run() render.destroyAllSprites() freaky:stop() state.changeState("playstate", curSong.name, curDiff, true) end local font = love.graphics.newFont("fonts/FridayNightFunkin-Regular.ttf", 40) local smallerFont = love.graphics.newFont("fonts/FridayNightFunkin-Regular.ttf", 20) local gettingKey local settings = json.parse(files.read_file("settings.json")) local keybinds = settings.Keybinds local scroll = love.audio.newSource("sounds/ui/scrollMenu.ogg", "static") local confirm = love.audio.newSource("sounds/ui/confirmMenu.ogg", "static") function state.update(dt) if start then startedPlaying = startedPlaying + dt if startedPlaying > .5 then run() end end lastChange = lastChange + dt if lastChange > .25 and bfAtlas.symbol == curChar .. " slide in" then bfAtlas:play(curChar .. " cs idle") end bfAtlas:update(dt) render.cameraTarget = Vector2(0, 0) render.updateSprites(dt) end function state.draw() love.graphics.setDefaultFilter("nearest", "nearest") render.drawSprites() evilCurIndex = Lerp(evilCurIndex, curIndex, .3) for index, song in next, songs do local color = index == curIndex and { 50, 50, 50 } or { 0, 0, 0 } love.graphics.print({ color, song.name }, font, 310 - (8 * math.abs(index - evilCurIndex)), love.graphics:getHeight() / 2 + (50 * (index - evilCurIndex - .7)), 0, 1, 1, 200) local icon = icons[song.name] if icon then icon.position = Vector2(50 - (8 * math.abs(index - evilCurIndex)), love.graphics:getHeight() / 2 + (50 * (index - evilCurIndex - .5))) end end arrow.position = Vector2(60 - 16 * math.abs(evilCurIndex - curIndex), love.graphics:getHeight() / 2 - ((evilCurIndex - curIndex + 1)) * 50) bfAtlas:draw(playableOffsets[curChar][bfAtlas.symbol].x, playableOffsets[curChar][bfAtlas.symbol].y, 0, playableFlips[bfAtlas.symbol] and -1 or 1, 1) -- if bfAtlas.symbol == curChar .. " slide in" then -- bfAtlas:draw(curChar == "bf" and 695 or 690, curChar == "bf" and 315 or 320, 0, flip and -1 or 1, 1) -- else -- bfAtlas:draw(curChar == "bf" and 700 or 1150, curChar == "bf" and 300 or 190, 0, flip and -1 or 1, 1) -- end if data.songs[curChar] and data.songs[curChar][curSong.name] and data.songs[curChar][curSong.name][curDiff] then local text = string.format("Accuracy: %s, Score: %s, Rank: %s", tostring(data.songs[curChar][curSong.name][curDiff].accuracy):sub(1, 5), data.songs[curChar][curSong.name][curDiff].score, data.songs[curChar][curSong.name][curDiff].rank) love.graphics.print({ { 0, 0, 0 }, text }, smallerFont, 1280 - text:len() * 10, 0) end end function state.keypressed(key, un, is) if key == "return" then start = true startedPlaying = 0 icons[curSong.name]:PlayAnimation("confirm", 24, false) confirm:stop() confirm:play() bfAtlas:play(string.format("%s cs confirm", curChar)) elseif key == "down" then curIndex, curSong = next(songs, curIndex) if not curSong then curIndex, curSong = next(songs) curDiffList = curSong.difficulties else curDiffList = curSong.difficulties end curDiffInd = 1 curDiff = curDiffList[1] diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "up" then --the solution was so stupid easy if songs[curIndex - 1] then curSong = songs[curIndex - 1] curDiffList = songs[curIndex - 1].difficulties curDiffInd = 1 curDiff = curDiffList[curDiffInd] curIndex = curIndex - 1 else curSong = songs[#songs] curIndex = #songs curDiffList = songs[curIndex].difficulties curDiffInd = 1 curDiff = curDiffList[curDiffInd] end curDiffInd = 1 curDiff = curDiffList[1] diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "right" then if curDiffList[curDiffInd + 1] then curDiff = curDiffList[curDiffInd + 1] curDiffInd = curDiffInd + 1 else curDiff = curDiffList[1] curDiffInd = 1 end diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "left" then if curDiffList[curDiffInd - 1] then curDiff = curDiffList[curDiffInd - 1] curDiffInd = curDiffInd - 1 else curDiff = curDiffList[#curDiffList] curDiffInd = #curDiffList end diffIMG:PlayAnimation(curDiff, 24, true) scroll:stop() scroll:play() elseif key == "p" then --changes character to/from pico hopefully arrow:Destroy() -- flip = true curCharIndex, curChar = next(playables, curCharIndex) if not curCharIndex then curCharIndex = 1 curChar = playables[1] end songs = require(string.format("charts.songs-%s", curChar)) --change which catalogue is available bfAtlas:stop() bfAtlas:load(string.format("sprites/charSelect/%sChill", curChar)) bfAtlas:play(string.format("%s slide in", curChar)) arrow = Sprite( string.format("sprites/freeplay/freeplaySelector-%s.png", curChar), string.format("sprites/freeplay/freeplaySelector-%s.json", curChar) ) arrow.position.y = 330 arrow.position.x = 20 arrow.layer = 1 arrow.resize = Vector2(.5, .5) arrow.flipX = true arrow:PlayAnimation("arrow pointer loop", 24, true) flip = false --reset the index's nd shit curSong = songs[1] curIndex = 1 evilCurIndex = 1 curDiffInd = 1 curDiffList = songs[curIndex].difficulties curDiff = curDiffList[1] diffIMG:PlayAnimation(curDiff, 24, true) iconNum = math.random(1, 3) charIcon:PlayAnimation(curChar .. iconNum, 24, false) charSwapSND:stop() charSwapSND:play() lastChange = 0 setupIcons() elseif key == "escape" then state.changeState("menustate") end end function state.load() setup() love.window.setMode(1280, 720, { fullscreen = false, resizable = false, centered = true, borderless = false }) end return state end