forked from Yonokid/PyTaikoGreen
62 lines
2.3 KiB
Lua
62 lines
2.3 KiB
Lua
-- ChibiWave: a BaseChibi that bobs up and down while it runs, and may rock side to side.
|
|
-- wave: { first = px from the run line to the first turn (+ is down), height = px between
|
|
-- the turns, beats = beats per swing }
|
|
-- sway: { first = degrees to the first lean (+ is forward), height = degrees between leans,
|
|
-- beats = beats per rock } (optional)
|
|
-- Both start when the chibi lands: the first swing only covers `first`, then each swing goes
|
|
-- the full height, back and forth.
|
|
local BaseChibi = require("background/bg_objects/chibi/base")
|
|
local Timing = require("background/bg_objects/timing")
|
|
local chain_moves, sum, Loop = Timing.chain_moves, Timing.sum, Timing.Loop
|
|
|
|
local Swing = {}
|
|
Swing.__index = Swing
|
|
|
|
function Swing.new(s, beat, unit, now)
|
|
local self = setmetatable({}, Swing)
|
|
local lead = s.beats * math.abs(s.first) / s.height
|
|
local dir = s.first > 0 and -1 or 1
|
|
self.lead = chain_moves({ { lead, s.first } }, beat, unit)
|
|
self.lead_end = now + lead * beat
|
|
self.loop = Loop.new(2 * s.beats * beat, function()
|
|
return { v = chain_moves({ { s.beats, dir * s.height }, { s.beats, -dir * s.height } }, beat, unit) }
|
|
end)
|
|
return self
|
|
end
|
|
|
|
function Swing:update(now)
|
|
for _, m in ipairs(self.lead) do m:update(now) end
|
|
if now >= self.lead_end then self.loop:update(now) end
|
|
end
|
|
|
|
function Swing:value()
|
|
return sum(self.lead) + (self.loop.anims and sum(self.loop.anims.v) or 0)
|
|
end
|
|
|
|
local ChibiWave = setmetatable({}, { __index = BaseChibi })
|
|
ChibiWave.__index = ChibiWave
|
|
|
|
function ChibiWave.new(spec, path, folder, bpm, is_2p)
|
|
local self = setmetatable({}, ChibiWave)
|
|
self:init(spec, path, folder, bpm, is_2p)
|
|
return self
|
|
end
|
|
|
|
function ChibiWave:update_extra(current_time_ms)
|
|
if self.hopping then return end
|
|
local spec = self.spec
|
|
self.bob = self.bob or Swing.new(spec.wave, self.beat, self.scale, current_time_ms)
|
|
self.rock = self.rock or (spec.sway and Swing.new(spec.sway, self.beat, 1, current_time_ms))
|
|
self.bob:update(current_time_ms)
|
|
if self.rock then self.rock:update(current_time_ms) end
|
|
end
|
|
|
|
function ChibiWave:place()
|
|
local at = BaseChibi.place(self)
|
|
if self.bob then at.y = at.y + self.bob:value() / self.scale end
|
|
if self.rock then at.rot = self.rock:value() end
|
|
return at
|
|
end
|
|
|
|
return ChibiWave
|