78 lines
3.4 KiB
Lua
78 lines
3.4 KiB
Lua
local DonBGBase = require("background/bg_objects/donbg/base")
|
|
|
|
-- SparkleDonBG: a DonBGBase band whose clear set has stars twinkling in clusters over it
|
|
-- (still, not scrolling), as in IMAS SideM and Love Live!. Both ensos place the clusters the
|
|
-- same way and time the stars the same way; only the star sizes differ, so each collab gives
|
|
-- its two star sets. Ambient, in ms.
|
|
--
|
|
-- Twinkles in a 2s cycle, counted in Lumen frames (120 a cycle): { pop, life, x, y, from, to }.
|
|
-- A star pops up to `from` size in 5 frames, grows to `to` until `life` frames after the pop
|
|
-- and shrinks away in 5 more. x, y: offset from the cluster's centre.
|
|
-- stars = { trio = (three stars taking turns), pair = (one star in the middle, the other
|
|
-- hopping between two spots) }; texture key "sparkle" is the 55px star.
|
|
local SPARKLE_MS, SPARKLE_FRAMES, SPARKLE_POP = 2000, 120, 5
|
|
local SPARKLE_PIVOT = 27.5 -- the star's centre in its image
|
|
|
|
-- clusters: { set, x, y, size } (a negative size turns the cluster round)
|
|
local CLUSTERS = {
|
|
{ "trio", 54.5, 28.5, 1 }, { "trio", 413.7, 32.7, -0.8 }, { "trio", 795.7, 170.2, 0.8 },
|
|
{ "trio", 228.75, 163.6, 0.5 }, { "trio", 578.95, 162.5, 1 }, { "trio", 894.4, 102, 0.5 },
|
|
{ "trio", 1057.45, 48, -1 }, { "trio", 1179.45, 117.1, 0.5 }, { "trio", 1292.45, 162.5, 1 },
|
|
{ "pair", 38.3, 114.35, 1 }, { "pair", 546.4, 44.35, 1 }, { "pair", 959, 148.4, 1 },
|
|
}
|
|
|
|
-- size and opacity of a twinkle `f` frames into the cycle (nil while it's hidden)
|
|
local function twinkle(s, f)
|
|
local pop, life, from, to = s[1], s[2], s[5], s[6]
|
|
local u = (f - pop) % SPARKLE_FRAMES
|
|
if u < SPARKLE_POP then return from * u / SPARKLE_POP, u / SPARKLE_POP end
|
|
if u < life then return from + (to - from) * (u - SPARKLE_POP) / (life - SPARKLE_POP), 1 end
|
|
if u < life + SPARKLE_POP then
|
|
local k = 1 - (u - life) / SPARKLE_POP
|
|
return to * k, 0.8 * k
|
|
end
|
|
end
|
|
|
|
local SparkleDonBG = setmetatable({}, { __index = DonBGBase })
|
|
SparkleDonBG.__index = SparkleDonBG
|
|
|
|
function SparkleDonBG.new(player_num, path, spec, stars)
|
|
local self = setmetatable(DonBGBase.new(1, player_num, path, spec), SparkleDonBG)
|
|
self._id_sparkle = tex.get_texture(path .. "/" .. self.name .. "/" .. "sparkle") or 0
|
|
self.sparkle_size = tex.get_texture_info(self.name, "sparkle").width
|
|
self.stars = stars
|
|
self.now = 0
|
|
return self
|
|
end
|
|
|
|
function SparkleDonBG:update(current_time_ms, bpm)
|
|
DonBGBase.update(self, current_time_ms, bpm)
|
|
self.now = current_time_ms
|
|
end
|
|
|
|
function SparkleDonBG:draw_band(y)
|
|
DonBGBase.draw_band(self, y)
|
|
if self.clear <= 0 then return end
|
|
local sc, w = tex.get_screen_scale(), self.sparkle_size
|
|
local f = (self.now % SPARKLE_MS) * SPARKLE_FRAMES / SPARKLE_MS
|
|
for _, c in ipairs(CLUSTERS) do
|
|
local k = c[4]
|
|
for _, s in ipairs(self.stars[c[1]]) do
|
|
local size, alpha = twinkle(s, f)
|
|
if size and size > 0 then
|
|
size = size * math.abs(k)
|
|
local o = SPARKLE_PIVOT * size * sc
|
|
tex.draw_texture(self._id_sparkle, {
|
|
x = (c[2] + s[3] * k) * sc, y = y + (c[3] + s[4] * k) * sc,
|
|
x2 = w * (size - 1), y2 = w * (size - 1), origin = { o, o },
|
|
fade = alpha * self.clear,
|
|
})
|
|
end
|
|
end
|
|
end
|
|
end
|
|
|
|
function SparkleDonBG:draw(y) self:draw_dark(SparkleDonBG.draw_band, y or 0) end
|
|
|
|
return SparkleDonBG
|