231 lines
6.9 KiB
Lua
231 lines
6.9 KiB
Lua
|
|
local Easing = require('common.easings');
|
|
|
|
local backgroundImage = gfx.CreateSkinImage("song_select/bg.png", 1)
|
|
local songPlateBg = gfx.CreateSkinImage("song_select/plate/bg.png", 1)
|
|
local songPlateBottomBarOverlayImage = gfx.CreateSkinImage("song_select/plate/bottom_bar_overlay.png", 1)
|
|
|
|
local cursorImage = gfx.CreateSkinImage("song_select/cursor.png", 1)
|
|
|
|
local defaultJacketImage = gfx.CreateSkinImage("song_select/loading.png", 0)
|
|
|
|
local difficultyLabelImages = {
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/novice.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/advanced.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/exhaust.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/maximum.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/infinite.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/gravity.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/heavenly.png", 1),
|
|
gfx.CreateSkinImage("song_select/plate/difficulty_labels/vivid.png", 1),
|
|
}
|
|
|
|
local badgeImages = {
|
|
gfx.CreateSkinImage("song_select/medal/nomedal.png", 1),
|
|
gfx.CreateSkinImage("song_select/medal/played.png", 1),
|
|
gfx.CreateSkinImage("song_select/medal/clear.png", 1),
|
|
gfx.CreateSkinImage("song_select/medal/hard.png", 1),
|
|
gfx.CreateSkinImage("song_select/medal/uc.png", 1),
|
|
gfx.CreateSkinImage("song_select/medal/puc.png", 1),
|
|
}
|
|
|
|
local difficultyNumbers;
|
|
|
|
local resx, resy = game.GetResolution()
|
|
local desw, desh;
|
|
local scale;
|
|
|
|
local songPlateHeight = 172;
|
|
|
|
local selectedIndex = 1;
|
|
local selectedDifficulty = 1;
|
|
|
|
local jacketCache = {}
|
|
|
|
local transitionScrollScale = 0;
|
|
local transitionScrollOffsetY = 0;
|
|
local scrollingUp = false;
|
|
|
|
function resetLayoutInformation()
|
|
resx, resy = game.GetResolution()
|
|
desw = 1080
|
|
desh = 1920
|
|
scale = resx / desw
|
|
end
|
|
|
|
function load_number_image(path)
|
|
local images = {}
|
|
for i = 0, 9 do
|
|
images[i + 1] = gfx.CreateSkinImage(string.format("%s/%d.png", path, i), 0)
|
|
end
|
|
return images
|
|
end
|
|
|
|
function draw_number(x, y, alpha, num, digits, images, is_dim, scale, kern)
|
|
scale = scale or 1;
|
|
kern = kern or 1;
|
|
local tw, th = gfx.ImageSize(images[1])
|
|
tw = tw * scale;
|
|
th = th * scale;
|
|
x = x + (tw * (digits - 1)) / 2
|
|
y = y - th / 2
|
|
for i = 1, digits do
|
|
local mul = 10 ^ (i - 1)
|
|
local digit = math.floor(num / mul) % 10
|
|
local a = alpha
|
|
if is_dim and num < mul then
|
|
a = 0.4
|
|
end
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(x, y, tw, th, images[digit + 1], a, 0)
|
|
x = x - (tw * kern)
|
|
end
|
|
end
|
|
|
|
function getCorrectedIndex(from, offset)
|
|
total = #songwheel.songs;
|
|
|
|
index = from + offset;
|
|
|
|
if index < 1 then
|
|
index = total + (from+offset) -- this only happens if the offset is negative
|
|
end;
|
|
|
|
if index > total then
|
|
indexesUntilEnd = total - from;
|
|
index = offset - indexesUntilEnd -- this only happens if the offset is positive
|
|
end;
|
|
|
|
return index;
|
|
end;
|
|
|
|
function getJacketImage(song)
|
|
if not jacketCache[song.id] then
|
|
jacketCache[song.id] = gfx.CreateImage(song.difficulties[1].jacketPath, 0)
|
|
end
|
|
|
|
return jacketCache[song.id];
|
|
end
|
|
|
|
function drawBackground()
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(0, 0, desw, desh, backgroundImage, 1, 0)
|
|
end
|
|
|
|
function drawSong(song, y)
|
|
local songX = desw/2+28
|
|
local selectedSongDifficulty = song.difficulties[selectedDifficulty]
|
|
local bestScore = selectedSongDifficulty.scores[1] or nil;
|
|
|
|
-- Draw the bg for the song plate
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(songX, y, 515, 172, songPlateBg, 1, 0)
|
|
|
|
-- Draw jacket
|
|
local jacketImage = getJacketImage(song);
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(songX+4, y+4, 163, 163, jacketImage or defaultJacketImage, 1, 0)
|
|
|
|
-- Draw the overlay for the song plate (that bottom black bar)
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(songX, y, 515, 172, songPlateBottomBarOverlayImage, 1, 0)
|
|
|
|
-- Draw the difficulty notch background
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(songX, y+95, 83, 74, difficultyLabelImages[selectedSongDifficulty.difficulty+1], 1, 0)
|
|
|
|
-- Draw the difficulty level number
|
|
gfx.BeginPath()
|
|
draw_number(songX+30, y+125, 1.0, selectedSongDifficulty.level, 2, difficultyNumbers, false, 0.65, 1)
|
|
|
|
-- Draw score badge
|
|
local badgeImage = badgeImages[1];
|
|
if bestScore then
|
|
badgeImage = badgeImages[bestScore.badge+1];
|
|
end
|
|
|
|
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(songX+282, y+44, 79, 69, badgeImage, 1, 0)
|
|
end
|
|
|
|
function drawSongList()
|
|
local numOfSongsAround = 7; -- How many songs should be up and how many should be down of the selected one
|
|
|
|
|
|
local i=1;
|
|
while (i <= numOfSongsAround) do
|
|
local songIndex = getCorrectedIndex(selectedIndex, -i)
|
|
drawSong(songwheel.songs[songIndex], desh/2-songPlateHeight/2-songPlateHeight*i + transitionScrollOffsetY)
|
|
i=i+1;
|
|
end;
|
|
|
|
-- Draw the selected song
|
|
drawSong(songwheel.songs[selectedIndex], desh/2-songPlateHeight/2 + transitionScrollOffsetY)
|
|
|
|
i=1;
|
|
while (i <= numOfSongsAround) do
|
|
local songIndex = getCorrectedIndex(selectedIndex, i)
|
|
drawSong(songwheel.songs[songIndex], desh/2-songPlateHeight/2+songPlateHeight*i + transitionScrollOffsetY)
|
|
i=i+1;
|
|
end;
|
|
end
|
|
|
|
function drawCursor()
|
|
gfx.BeginPath()
|
|
gfx.ImageRect(desw/2-14, desh/2-213/2, 555, 213, cursorImage, 1, 0)
|
|
end
|
|
|
|
function tickTransitions(deltaTime)
|
|
if transitionScrollScale < 1 then
|
|
transitionScrollScale = transitionScrollScale + deltaTime / 0.1 -- transition should last for that time in seconds
|
|
else
|
|
transitionScrollScale = 1
|
|
end
|
|
|
|
if scrollingUp then
|
|
transitionScrollOffsetY = Easing.inQuad(1-transitionScrollScale) * songPlateHeight;
|
|
else
|
|
transitionScrollOffsetY = Easing.inQuad(1-transitionScrollScale) * -songPlateHeight;
|
|
end
|
|
end
|
|
|
|
render = function (deltaTime)
|
|
resetLayoutInformation();
|
|
tickTransitions(deltaTime);
|
|
gfx.Scale(scale, scale);
|
|
|
|
if not difficultyNumbers then
|
|
difficultyNumbers = load_number_image('diff_num')
|
|
end
|
|
|
|
drawBackground();
|
|
|
|
drawSongList()
|
|
drawCursor()
|
|
|
|
|
|
gfx.BeginPath();
|
|
gfx.FontSize(18)
|
|
gfx.TextAlign(gfx.TEXT_ALIGN_LEFT + gfx.TEXT_ALIGN_TOP)
|
|
local debugScrollingUp= "FALSE"
|
|
if scrollingUp then debugScrollingUp = "TRUE" end;
|
|
gfx.Text('DELTA: ' .. deltaTime .. ' // SELECTED_INDEX: ' .. selectedIndex .. ' // SELECTED_DIFF: ' .. selectedDifficulty .. ' // SCROLLING_UP: ' .. debugScrollingUp, 8, 8);
|
|
end
|
|
|
|
set_index = function(newIndex)
|
|
transitionScrollScale = 0;
|
|
|
|
scrollingUp = false;
|
|
if ((newIndex > selectedIndex and not (newIndex == #songwheel.songs and selectedIndex == 1)) or (newIndex == 1 and selectedIndex == #songwheel.songs)) then
|
|
scrollingUp = true;
|
|
end;
|
|
|
|
-- TODO: add sfx for cursor change
|
|
|
|
selectedIndex = newIndex;
|
|
end;
|
|
|
|
set_diff = function(newDiff)
|
|
selectedDifficulty = newDiff;
|
|
end; |