Notes: the cabinet's flight and big-note sparkle trail #70
No files matched your search
Binary file not shown.
@@ -146,5 +146,87 @@
|
|||||||
336
|
336
|
||||||
]
|
]
|
||||||
]
|
]
|
||||||
|
},
|
||||||
|
"firework": {
|
||||||
|
"crop": [
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
0,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
256,
|
||||||
|
0,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
512,
|
||||||
|
0,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
768,
|
||||||
|
0,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
512,
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
768,
|
||||||
|
256,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
512,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
256,
|
||||||
|
512,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
512,
|
||||||
|
512,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
768,
|
||||||
|
512,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
],
|
||||||
|
[
|
||||||
|
0,
|
||||||
|
768,
|
||||||
|
256,
|
||||||
|
256
|
||||||
|
]
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,94 @@
|
|||||||
|
-- This skin's note arc: the parent's script with the flight and the big-note sparks redone as
|
||||||
|
-- the cabinet's (onp_jump):
|
||||||
|
-- * the note flies from the judge circle to 魂 in 30 frames on the cabinet's path, here a
|
||||||
|
-- cubic Bezier fitted to it (within 6 px), P1 arcing up and P2 down, each with its own fit;
|
||||||
|
-- it then waits at 魂 until the engine's flight (31 frames) ends
|
||||||
|
-- * a big note leaves 9 sparks (hit_effect/firework, the cabinet's 13-frame spark on black),
|
||||||
|
-- the first at frame 5 and then every 3 frames, each centred where the note was about 2
|
||||||
|
-- frames before, at full size, added onto the scene
|
||||||
|
-- The balloon keeps the parent's flight and rainbow (the cabinet's balloon has its own path).
|
||||||
|
-- Everything else is the parent's file, loaded from its own copy.
|
||||||
|
|
||||||
|
-- the parent skin's copy of a script: the second match on package.path (the first is this file)
|
||||||
|
local function load_parent(name)
|
||||||
|
local seen = false
|
||||||
|
for tmpl in package.path:gmatch("[^;]+") do
|
||||||
|
local chunk = loadfile((tmpl:gsub("%?", name)))
|
||||||
|
if chunk then
|
||||||
|
if seen then return chunk end
|
||||||
|
seen = true
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
assert(load_parent("game/note_arc"), "game/note_arc: the parent skin has no note_arc script")()
|
||||||
|
|
||||||
|
local FRAME_MS = 16.67
|
||||||
|
local FLIGHT_MS = 30 * FRAME_MS
|
||||||
|
-- control points as offsets from the start (c1) and from the end (c2)
|
||||||
|
local CONTROL = {
|
||||||
|
[1] = { c1x = 196.8, c1y = -474.8, c2x = -300.4, c2y = -419.3 },
|
||||||
|
[2] = { c1x = 178.5, c1y = 486.4, c2x = -314.9, c2y = 414.3 },
|
||||||
|
}
|
||||||
|
-- sparks: spawn frames, and where each sits on the 30-frame flight (frames)
|
||||||
|
local SPARK_COUNT = 9
|
||||||
|
local SPARK_SPAWN, SPARK_SPAWN_STEP = 5, 3
|
||||||
|
local SPARK_AT, SPARK_AT_STEP = 2.58, 3.085
|
||||||
|
|
||||||
|
local parent_new = NoteArc.new
|
||||||
|
function NoteArc.new(note_tex_type, big, is_balloon, player_num, start_x, start_y)
|
||||||
|
local self = parent_new(note_tex_type, big, is_balloon, player_num, start_x, start_y)
|
||||||
|
local c = CONTROL[self.p2 and 2 or 1]
|
||||||
|
self.c1x, self.c1y = self.sx + c.c1x, self.sy + c.c1y
|
||||||
|
self.c2x, self.c2y = self.ex + c.c2x, self.ey + c.c2y
|
||||||
|
|
||||||
|
-- a spark is centred on the note: both textures' own offsets and sizes
|
||||||
|
local note = tex.get_texture_info("notes", tostring(note_tex_type))
|
||||||
|
local spark = self.t_firework and tex.get_texture_info("hit_effect", "firework")
|
||||||
|
if note and spark then
|
||||||
|
self.spark_dx = note.x[1] - spark.x[1] + (note.x2[1] - spark.x2[1]) / 2
|
||||||
|
self.spark_dy = note.y[1] - spark.y[1] + (note.y2[1] - spark.y2[1]) / 2
|
||||||
|
end
|
||||||
|
return self
|
||||||
|
end
|
||||||
|
|
||||||
|
local parent_point = NoteArc.point
|
||||||
|
local parent_draw = NoteArc.draw
|
||||||
|
|
||||||
|
-- the cabinet's flight, progress 0..1 over its 30 frames
|
||||||
|
function NoteArc:point(progress)
|
||||||
|
if self.is_balloon then return parent_point(self, progress) end
|
||||||
|
local t = math.max(0, math.min(1, progress))
|
||||||
|
local u = 1 - t
|
||||||
|
local b0, b1, b2, b3 = u * u * u, 3 * u * u * t, 3 * u * t * t, t * t * t
|
||||||
|
return b0 * self.sx + b1 * self.c1x + b2 * self.c2x + b3 * self.ex,
|
||||||
|
b0 * self.sy + b1 * self.c1y + b2 * self.c2y + b3 * self.ey
|
||||||
|
end
|
||||||
|
|
||||||
|
function NoteArc:draw_fireworks(y, elapsed_ms)
|
||||||
|
if not self.spark_dx then return end
|
||||||
|
for i = 0, SPARK_COUNT - 1 do
|
||||||
|
local age_ms = elapsed_ms - (SPARK_SPAWN + SPARK_SPAWN_STEP * i) * FRAME_MS
|
||||||
|
local frame = math.floor(age_ms / FRAME_MS)
|
||||||
|
if age_ms >= 0 and frame < self.firework_frames then
|
||||||
|
local fx, fy = self:point((SPARK_AT + SPARK_AT_STEP * i) * FRAME_MS / FLIGHT_MS)
|
||||||
|
tex.draw_texture(self.t_firework, {
|
||||||
|
frame = frame, center = true, blend = "additive",
|
||||||
|
x = fx + self.spark_dx, y = y + fy + self.spark_dy,
|
||||||
|
})
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
function NoteArc:draw(y, elapsed_ms, duration_ms)
|
||||||
|
if self.is_balloon then return parent_draw(self, y, elapsed_ms, duration_ms) end
|
||||||
|
if self.big and self.t_firework and self.firework_frames > 0 then
|
||||||
|
self:draw_fireworks(y, elapsed_ms)
|
||||||
|
end
|
||||||
|
if elapsed_ms < duration_ms then
|
||||||
|
local x_i, y_i = self:point(elapsed_ms / FLIGHT_MS)
|
||||||
|
tex.draw_texture(self.t_note, { x = x_i, y = y + y_i })
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
return NoteArc
|
||||||
Reference in new issue
Block a user