213 lines
6.8 KiB
Lua
213 lines
6.8 KiB
Lua
local BaseRenda = {}
|
|
BaseRenda.__index = BaseRenda
|
|
|
|
function BaseRenda.new(index, path)
|
|
local self = setmetatable({}, BaseRenda)
|
|
self.name = "renda_" .. index
|
|
self.path = path
|
|
local screen_width = tex.get_screen_width()
|
|
local screen_scale = tex.get_screen_scale()
|
|
self.hori_move = anim.move(1500 * screen_scale, {total_distance = screen_width})
|
|
self.hori_move:start()
|
|
return self
|
|
end
|
|
|
|
function BaseRenda:update(current_time_ms)
|
|
self.hori_move:update(current_time_ms)
|
|
end
|
|
|
|
local Renda0 = setmetatable({}, {__index = BaseRenda})
|
|
Renda0.__index = Renda0
|
|
|
|
function Renda0.new(index, path)
|
|
local self = setmetatable({}, Renda0)
|
|
local base = BaseRenda.new(index, path)
|
|
for k, v in pairs(base) do self[k] = v end
|
|
local screen_scale = tex.get_screen_scale()
|
|
local screen_height = tex.get_screen_height()
|
|
self.vert_move = anim.move(1500 * screen_scale, {total_distance = screen_height + (80 * screen_scale)})
|
|
self.vert_move:start()
|
|
local tex_info = tex.get_texture_info("renda", self.name)
|
|
local num_frames = (tex_info and tex_info.frame_count) or 1
|
|
self.frame = math.random(0, num_frames - 1)
|
|
self.x = math.random(0, math.floor(500 * screen_scale))
|
|
self.y = math.random(0, math.floor(20 * screen_scale))
|
|
self._id = tex.get_texture(self.path .. "/renda/" .. self.name) or 0
|
|
return self
|
|
end
|
|
|
|
function Renda0:update(current_time_ms)
|
|
BaseRenda.update(self, current_time_ms)
|
|
self.vert_move:update(current_time_ms)
|
|
end
|
|
|
|
function Renda0:draw()
|
|
tex.draw_texture(self._id, {
|
|
frame = self.frame,
|
|
x = self.hori_move.attribute + self.x,
|
|
y = -self.vert_move.attribute + self.y
|
|
})
|
|
end
|
|
|
|
local Renda1 = setmetatable({}, {__index = BaseRenda})
|
|
Renda1.__index = Renda1
|
|
|
|
function Renda1.new(index, path)
|
|
local self = setmetatable({}, Renda1)
|
|
local base = BaseRenda.new(index, path)
|
|
for k, v in pairs(base) do self[k] = v end
|
|
local screen_scale = tex.get_screen_scale()
|
|
local screen_height = tex.get_screen_height()
|
|
self.frame = math.random(0, 5)
|
|
self.y = math.random(0, math.floor(200 * screen_scale))
|
|
self.rotate = anim.move(800 * screen_scale, {total_distance = math.floor(screen_height / 2), loop = true})
|
|
self.rotate:start()
|
|
self.origin = {64, 64}
|
|
self._id = tex.get_texture(self.path .. "/renda/" .. self.name) or 0
|
|
return self
|
|
end
|
|
|
|
function Renda1:update(current_time_ms)
|
|
BaseRenda.update(self, current_time_ms)
|
|
self.rotate:update(current_time_ms)
|
|
end
|
|
|
|
function Renda1:draw()
|
|
tex.draw_texture(self._id, {
|
|
frame = self.frame,
|
|
x = self.hori_move.attribute + self.origin[1],
|
|
y = self.y + self.origin[2],
|
|
origin = self.origin,
|
|
rotation = self.rotate.attribute
|
|
})
|
|
end
|
|
|
|
local Renda2 = setmetatable({}, {__index = BaseRenda})
|
|
Renda2.__index = Renda2
|
|
|
|
function Renda2.new(index, path)
|
|
local self = setmetatable({}, Renda2)
|
|
local base = BaseRenda.new(index, path)
|
|
for k, v in pairs(base) do self[k] = v end
|
|
local screen_scale = tex.get_screen_scale()
|
|
local screen_height = tex.get_screen_height()
|
|
self.vert_move = anim.move(1500, {total_distance = screen_height + (80 * screen_scale)})
|
|
self.vert_move:start()
|
|
self.x = math.random(0, math.floor(500 * screen_scale))
|
|
self.y = math.random(0, math.floor(20 * screen_scale))
|
|
self._id = tex.get_texture(self.path .. "/renda/" .. self.name) or 0
|
|
return self
|
|
end
|
|
|
|
function Renda2:update(current_time_ms)
|
|
BaseRenda.update(self, current_time_ms)
|
|
self.vert_move:update(current_time_ms)
|
|
end
|
|
|
|
function Renda2:draw()
|
|
tex.draw_texture(self._id, {
|
|
x = self.hori_move.attribute + self.x,
|
|
y = -self.vert_move.attribute + self.y
|
|
})
|
|
end
|
|
|
|
local RendaController = {}
|
|
RendaController.__index = RendaController
|
|
|
|
function RendaController.new(path, index)
|
|
local self = setmetatable({}, RendaController)
|
|
self.rendas = {}
|
|
self.path = path or "background"
|
|
self.index = (index ~= nil) and index or math.random(0, 2)
|
|
tex.load_folder(self.path, "renda")
|
|
return self
|
|
end
|
|
|
|
function RendaController:add_renda()
|
|
local classes = {Renda0, Renda1, Renda2}
|
|
local cls = classes[self.index + 1]
|
|
table.insert(self.rendas, cls.new(self.index, self.path))
|
|
end
|
|
|
|
function RendaController:update(current_time_ms)
|
|
for i = #self.rendas, 1, -1 do
|
|
self.rendas[i]:update(current_time_ms)
|
|
if self.rendas[i].hori_move.is_finished then
|
|
table.remove(self.rendas, i)
|
|
end
|
|
end
|
|
end
|
|
|
|
function RendaController:draw()
|
|
for _, renda in ipairs(self.rendas) do
|
|
renda:draw()
|
|
end
|
|
end
|
|
|
|
function RendaController:destroy()
|
|
tex.unload_folder(self.path, "renda")
|
|
end
|
|
|
|
-- LumenRenda: the Lumen collabs' drumroll (Miku, GUMI). Every hit sends two notes flying straight across from the right edge,
|
|
-- each one of the five pictures at one of two speeds
|
|
local RENDA_KINDS = { -- { frame, flight ms }
|
|
{ 0, 1333 }, { 0, 2000 }, { 1, 1667 }, { 1, 2000 }, { 2, 2333 },
|
|
{ 2, 2000 }, { 3, 1667 }, { 3, 2000 }, { 4, 1333 }, { 4, 2000 },
|
|
}
|
|
local RENDA_PER_HIT = 2
|
|
local RENDA_LIMIT = 25
|
|
local RENDA_DISTANCE = 2060
|
|
-- where a note starts (its top-left). The original takes these from the game rather
|
|
-- than the animation data, so they are picked to start just off the right edge and
|
|
-- fly over the stage below the lane
|
|
local RENDA_X, RENDA_X_RANGE = 1280, 200
|
|
local RENDA_Y, RENDA_Y_RANGE = 384, 288
|
|
|
|
local LumenRenda = {}
|
|
LumenRenda.__index = LumenRenda
|
|
|
|
function LumenRenda.new(path)
|
|
local self = setmetatable({}, LumenRenda)
|
|
self.path = path
|
|
tex.load_folder(path, "renda")
|
|
self._id = tex.get_texture(self.path .. "/renda/renda_0") or 0
|
|
self.notes = {}
|
|
return self
|
|
end
|
|
|
|
function LumenRenda:add_renda()
|
|
local scale = tex.get_screen_scale()
|
|
for _ = 1, RENDA_PER_HIT do
|
|
if #self.notes >= RENDA_LIMIT then return end
|
|
local kind = RENDA_KINDS[math.random(#RENDA_KINDS)]
|
|
local move = anim.move(kind[2], { total_distance = -math.floor(RENDA_DISTANCE * scale) })
|
|
move:start()
|
|
table.insert(self.notes, {
|
|
frame = kind[1],
|
|
x = math.floor((RENDA_X + math.random(0, RENDA_X_RANGE)) * scale),
|
|
y = math.floor((RENDA_Y + math.random(0, RENDA_Y_RANGE)) * scale),
|
|
move = move,
|
|
})
|
|
end
|
|
end
|
|
|
|
function LumenRenda:update(current_time_ms)
|
|
for i = #self.notes, 1, -1 do
|
|
local note = self.notes[i]
|
|
note.move:update(current_time_ms)
|
|
if note.move.is_finished then table.remove(self.notes, i) end
|
|
end
|
|
end
|
|
|
|
function LumenRenda:draw()
|
|
for _, note in ipairs(self.notes) do
|
|
tex.draw_texture(self._id, { frame = note.frame, x = note.x + note.move.attribute, y = note.y })
|
|
end
|
|
end
|
|
|
|
function LumenRenda:destroy() tex.unload_folder(self.path, "renda") end
|
|
|
|
RendaController.Lumen = LumenRenda
|
|
|
|
return RendaController
|