Added atlas support and fixed a multitude of bugs

This commit is contained in:
entar 2025-06-21 16:45:14 +07:00
parent 4a18444306
commit a7dd8a1c36
5 changed files with 99 additions and 32 deletions

View File

@ -18,16 +18,18 @@ local logging = require("modules.logging")
require("modules.loveanimate") -- Start loveanimate
local songs = require("charts.songs")
local unparsedData = files.read_file("Saves.json")
print(dataFolder, unparsedData)
local unparsedData = files.read_file(dataFolder.."/Data.json")
local data = unparsedData and json.parse(unparsedData) or
{
songs = {
tutorial = {
hard = {
accuracy = 100,
score = 100000,
rank = "Perfect"
bf = {
tutorial = {
hard = {
accuracy = 100,
score = 100000,
rank = "Perfect"
}
}
}
}
@ -244,8 +246,8 @@ function love.draw()
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[curSong.name] and data.songs[curSong.name][curDiff] then
local text = string.format("Accuracy: %s, Score: %s, Rank: %s", tostring(data.songs[curSong.name][curDiff].accuracy):sub(1, 5), data.songs[curSong.name][curDiff].score, data.songs[curSong.name][curDiff].rank)
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
@ -289,23 +291,31 @@ function run()
curState.quit = function(accuracy, score)
if accuracy then
if not data.songs[curSong.name] then
data.songs[curSong.name] = {}
data.songs[curSong.name][curDiff] = {
if not data.songs[curChar] then
data.songs[curChar] = {}
data.songs[curChar][curSong.name] = {}
data.songs[curChar][curSong.name][curDiff] = {
accuracy = accuracy,
score = score,
rank = getRank(accuracy)
}
elseif not data.songs[curChar][curSong.name] then
data.songs[curChar][curSong.name] = {}
data.songs[curChar][curSong.name][curDiff] = {
accuracy = accuracy,
score = score,
rank = getRank(accuracy)
}
end
if data.songs[curSong.name][curDiff] and accuracy > data.songs[curSong.name][curDiff].accuracy or not data.songs[curSong.name][curDiff] then
data.songs[curSong.name][curDiff] = {
if data.songs[curChar][curSong.name][curDiff] and accuracy > data.songs[curChar][curSong.name][curDiff].accuracy or not data.songs[curChar][curSong.name][curDiff] then
data.songs[curChar][curSong.name][curDiff] = {
accuracy = accuracy,
score = score,
rank = getRank(accuracy)
}
end
end
files.write_file("Saves.json", json.stringify(data))
love.filesystem.write("Data.json", json.stringify(data))
curState = nil
stateLoaded = false
myTypes.destroyAllSprites()

View File

@ -192,7 +192,7 @@ local function state(songName, songDifficulty)
shouldCountdown = true,
}
local function quit()
local function quit(save)
if restart then return end
playing = false
@ -226,7 +226,7 @@ local function state(songName, songDifficulty)
gameOverEnd:stop()
end
state.quit(not dead and math.abs(score) > 0 and accuracy, not dead and math.abs(score) > 0 and score)
state.quit(save and not dead and math.abs(score) > 0 and accuracy, save and not dead and math.abs(score) > 0 and score)
end
local function die()
@ -447,8 +447,8 @@ local function state(songName, songDifficulty)
myTypes.render.cameraTarget = myTypes.Vector2(stage.camera_girlfriend[1], stage.camera_girlfriend[2]):Add(characters.gf.stageCamera:Negate()):Add(myTypes.Vector2(0, -200)):Add(currentSingVector)
end
else
local currentSingVector = sharedVars.singVectors[characters.dad.animation] or myTypes.Vector2()
myTypes.render.cameraTarget = myTypes.Vector2(stage.camera_opponent[1], stage.camera_opponent[2]):Add(characters.dad.stageCamera:Negate()):Add(myTypes.Vector2(0, -200))
local currentSingVector = sharedVars.singVectors[characters.bf.animation] or myTypes.Vector2()
myTypes.render.cameraTarget = myTypes.Vector2(-stage.camera_boyfriend[1], -stage.camera_boyfriend[2]):Add(characters.bf.stageCamera:Negate()):Add(myTypes.Vector2(0, -200)):Add(currentSingVector)
end
myTypes.updateSprites(dt)
@ -511,9 +511,9 @@ local function state(songName, songDifficulty)
characters.gf:PlayAnimation("sing"..directions[note.direction])
end
else
if section.altAnim or note.altAnim then
if section.altAnim or note.altAnim and characters.dad.animInfo["sing"..directions[note.direction].."-alt"] then
characters.dad:PlayAnimation("sing"..directions[note.direction].."-alt")
else
elseif characters.dad.animInfo["sing"..directions[note.direction]] then
characters.dad:PlayAnimation("sing"..directions[note.direction])
end
end
@ -565,6 +565,7 @@ local function state(songName, songDifficulty)
events[index] = nil
if event.name == "change character" then
characters[event.var1]:Destroy()
characters[event.var1] = myTypes.character(event.var2)
elseif event.name == "play animation" then
characters[event.var2]:PlayAnimation(event.var1)
@ -603,7 +604,7 @@ local function state(songName, songDifficulty)
end
if inst and not inst:isPlaying() and not counting then
quit()
quit(true)
end
::continue::
@ -620,6 +621,12 @@ local function state(songName, songDifficulty)
myTypes.drawSprites()
for i, module in next, modules do
if module.drawBelowUI then
module.drawBelowUI() --mainly for cutscenes i guess
end
end
love.graphics.setCanvas(uiCanvas)
love.graphics.clear()
@ -793,8 +800,8 @@ local function state(songName, songDifficulty)
local newEvent = {
time = note[1],
name = string.lower(note[3]),
var1 = string.lower(note[4]) or "",
var2 = string.lower(note[5]) or ""
var1 = note[4] or "",
var2 = note[5] or ""
}
events[#events+1] = newEvent
@ -819,8 +826,8 @@ local function state(songName, songDifficulty)
local newEvent = {
time = note[1],
name = string.lower(note[3]),
var1 = string.lower(note[4] or ""),
var2 = string.lower(note[5] or "")
var1 = note[4] or "",
var2 = note[5] or ""
}
events[#events+1] = newEvent
@ -840,10 +847,10 @@ local function state(songName, songDifficulty)
local newEvent = {
time = event[1],
name = string.lower(event[2][index][1]),
var1 = string.lower(event[2][index][2]),
var2 = string.lower(event[2][index][3])
var1 = event[2][index][2],
var2 = event[2][index][3]
}
logging.log(newEvent.name)
print(logging.dump(newEvent))
events[#events+1] = newEvent
if newEvent.name == "change character" then
@ -865,8 +872,8 @@ local function state(songName, songDifficulty)
local newEvent = {
time = event[1],
name = string.lower(event[2][index][1]),
var1 = string.lower(event[2][index][2]),
var2 = string.lower(event[2][index][3])
var1 = event[2][index][2],
var2 = event[2][index][3]
}
logging.log(newEvent.name)
events[#events+1] = newEvent
@ -991,6 +998,10 @@ local function state(songName, songDifficulty)
volume = volume ~= 0 and volume - 10 or 0
elseif key == "+" or key == "=" then
volume = volume ~= 100 and volume + 10 or 100
elseif key == "9" then
startTime = startTime - 200000
inst:seek(inst:tell() + (200000)/1000)
voices:seek(voices:tell() + (200000)/1000)
end
end

View File

@ -28,6 +28,11 @@ function CharacterClass:PlayAnimation(name)
self.animation = name
end
function CharacterClass:Destroy()
self.sprite:Destroy()
self = nil
end
function module.character(name)
local charFile = files.read_file(string.format("characters/%s.json", name))
if not charFile then

View File

@ -10,6 +10,7 @@ module.note = noteclass.note
characterclass.myTypes = module
module.character = characterclass.character
module.preloadChar = characterclass.preload
renderClasses.myTypes = module
module.Sprite = renderClasses.Sprite

View File

@ -14,7 +14,7 @@ local cachedImages = {}
local loadedShaders = {}
local Sprites, Rects, Images = {}, {}, {}
local Sprites, Rects, Images, Atlases = {}, {}, {}, {}
function module.Sprite(image, sheet)
if not cachedQuads[sheet] then
@ -173,6 +173,10 @@ function module.updateSprites(dt)
::continue:: -- At the end. always.
end
for index, Atlas in next, Atlases do
Atlas.atlas:update(dt)
end
if not module.cameraPosition then
module.cameraPosition = module.myTypes.Vector2()
end
@ -201,6 +205,11 @@ function module.drawSprites()
rect.isRect = true
end
for index, atlas in next, Atlases do
everything[#everything+1] = atlas
atlas.isAtlas = true
end
table.sort(everything, function(a, b)
return a.layer < b.layer
end)
@ -262,6 +271,10 @@ function module.drawSprites()
love.graphics.setShader()
end
elseif thing.isAtlas then
local cameraOffset = thing.ui and module.myTypes.Vector2() or module.cameraPosition or module.myTypes.Vector2()
thing.atlas:draw(thing.position.x + cameraOffset.x, thing.position.y + cameraOffset.y, thing.rotation, thing.resize.x, thing.resize.y)
end
::continue::
@ -483,4 +496,31 @@ function module.getShader(name)
return loadedShaders[name]
end
local Atlas = {}
Atlas.__index = Atlas
function Atlas:PlayAnimation(name)
self.atlas:play(name)
end
function Atlas:Destroy()
Atlases[self.index] = nil
end
function module.Atlas(folder)
local newAtlas = setmetatable({
atlas = love.animate.newTextureAtlas(),
position = module.myTypes.Vector2(),
rotation = 0,
resize = module.myTypes.Vector2(1,1),
index = 0
}, Atlas)
newAtlas.atlas:load(folder)
newAtlas.isAtlas = true
Atlases[#Atlases+1] = newAtlas
newAtlas.index = #Atlases
return newAtlas
end
return module