204 lines
11 KiB
GDScript3
204 lines
11 KiB
GDScript3
|
extends Node
|
||
|
|
||
|
const SQRT2 := sqrt(2)
|
||
|
const DEG45 := deg2rad(45.0)
|
||
|
const DEG90 := deg2rad(90.0)
|
||
|
const DEG135 := deg2rad(135.0)
|
||
|
|
||
|
# ----------------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
# Helper functions to generate meshes from vertex arrays
|
||
|
static func make_tap_mesh(mesh: ArrayMesh, note_center: Vector2, scale:=1.0, color_array:=GameTheme.COLOR_ARRAY_TAP):
|
||
|
var dim = GameTheme.sprite_size2 * scale
|
||
|
var vertex_array = PoolVector2Array([note_center + Vector2(-dim, -dim), note_center + Vector2(dim, -dim), note_center + Vector2(-dim, dim), note_center + Vector2(dim, dim)])
|
||
|
var arrays = []
|
||
|
arrays.resize(Mesh.ARRAY_MAX)
|
||
|
arrays[Mesh.ARRAY_VERTEX] = vertex_array
|
||
|
arrays[Mesh.ARRAY_TEX_UV] = GameTheme.UV_ARRAY_TAP
|
||
|
arrays[Mesh.ARRAY_COLOR] = color_array
|
||
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays)
|
||
|
|
||
|
static func make_hold_mesh(mesh: ArrayMesh, note_center: Vector2, note_center_rel: Vector2, scale:=1.0, angle:=0.0, color_array = GameTheme.COLOR_ARRAY_HOLD):
|
||
|
var dim = GameTheme.sprite_size2 * scale
|
||
|
var dim2 = dim * SQRT2
|
||
|
var a1 = angle - DEG45
|
||
|
var a2 = angle + DEG45
|
||
|
var a3 = angle - DEG90
|
||
|
var a4 = angle + DEG90
|
||
|
var a5 = angle - DEG135
|
||
|
var a6 = angle + DEG135
|
||
|
var vertex_array = PoolVector2Array([
|
||
|
note_center + polar2cartesian(dim2, a1), note_center + polar2cartesian(dim2, a2),
|
||
|
note_center + polar2cartesian(dim, a3), note_center + polar2cartesian(dim, a4),
|
||
|
note_center_rel + polar2cartesian(dim, a3), note_center_rel + polar2cartesian(dim, a4),
|
||
|
note_center_rel + polar2cartesian(dim2, a5), note_center_rel + polar2cartesian(dim2, a6)
|
||
|
])
|
||
|
var arrays = []
|
||
|
arrays.resize(Mesh.ARRAY_MAX)
|
||
|
arrays[Mesh.ARRAY_VERTEX] = vertex_array
|
||
|
arrays[Mesh.ARRAY_TEX_UV] = GameTheme.UV_ARRAY_HOLD
|
||
|
arrays[Mesh.ARRAY_COLOR] = color_array
|
||
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays)
|
||
|
|
||
|
static func make_star_mesh(mesh: ArrayMesh, note_center: Vector2, scale:=1.0, angle:=0.0, color_array:=GameTheme.COLOR_ARRAY_STAR):
|
||
|
var dim = GameTheme.sprite_size2 * scale * SQRT2
|
||
|
var a1 = angle - DEG45
|
||
|
var a2 = angle + DEG45
|
||
|
var a3 = angle - DEG135
|
||
|
var a4 = angle + DEG135
|
||
|
var vertex_array = PoolVector2Array([
|
||
|
note_center + polar2cartesian(dim, a1), note_center + polar2cartesian(dim, a2),
|
||
|
note_center + polar2cartesian(dim, a3), note_center + polar2cartesian(dim, a4)
|
||
|
])
|
||
|
var arrays = []
|
||
|
arrays.resize(Mesh.ARRAY_MAX)
|
||
|
arrays[Mesh.ARRAY_VERTEX] = vertex_array
|
||
|
arrays[Mesh.ARRAY_TEX_UV] = GameTheme.UV_ARRAY_STAR
|
||
|
arrays[Mesh.ARRAY_COLOR] = color_array
|
||
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays)
|
||
|
|
||
|
#func make_arrow_mesh(mesh: ArrayMesh, vertex_array, color_array = GameTheme.COLOR_ARRAY_TAP):
|
||
|
# var arrays = []
|
||
|
# arrays.resize(Mesh.ARRAY_MAX)
|
||
|
# arrays[Mesh.ARRAY_VERTEX] = vertex_array
|
||
|
# arrays[Mesh.ARRAY_TEX_UV] = UV_ARRAY_ARROW
|
||
|
# arrays[Mesh.ARRAY_COLOR] = color_array
|
||
|
# mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays)
|
||
|
|
||
|
|
||
|
const slide_arrows_per_unit_length := 10
|
||
|
static func make_slide_trail_mesh(note) -> ArrayMesh:
|
||
|
# Generates a mesh centered around origin. Make sure the MeshInstance2D that draws this is centered on the screen.
|
||
|
var mesh = ArrayMesh.new()
|
||
|
var arrays = []
|
||
|
arrays.resize(Mesh.ARRAY_MAX)
|
||
|
var vertices := PoolVector2Array()
|
||
|
var uvs := PoolVector2Array()
|
||
|
var colors := PoolColorArray()
|
||
|
var size := GameTheme.sprite_size2 * sqrt(2)
|
||
|
var color := GameTheme.COLOR_DOUBLE_SLIDE if note.double_hit else GameTheme.COLOR_SLIDE
|
||
|
|
||
|
match note.get_points():
|
||
|
[var positions, var angles]:
|
||
|
var trail_length : int = len(positions)
|
||
|
vertices.resize(3*trail_length)
|
||
|
uvs.resize(3*trail_length)
|
||
|
colors.resize(3*trail_length)
|
||
|
for i in trail_length:
|
||
|
var idx = (trail_length-i-1)*3 # We want the earliest ones to be drawn last so that loops/sharp bends will have the first pass on top
|
||
|
var u = GameTheme.UV_ARRAY_SLIDE_ARROW if i%3 else GameTheme.UV_ARRAY_SLIDE_ARROW2
|
||
|
for j in 3:
|
||
|
uvs[idx+j] = u[j]
|
||
|
colors[idx+j] = Color(color.r, color.g, color.b, (1.0+float(i))/float(trail_length))
|
||
|
var angle : float = angles[i]
|
||
|
var offset : Vector2 = positions[i] * GameTheme.receptor_ring_radius
|
||
|
vertices[idx] = offset
|
||
|
vertices[idx+1] = offset + polar2cartesian(size, angle+PI*0.75)
|
||
|
vertices[idx+2] = offset + polar2cartesian(size, angle-PI*0.75)
|
||
|
|
||
|
arrays[Mesh.ARRAY_VERTEX] = vertices
|
||
|
arrays[Mesh.ARRAY_TEX_UV] = uvs
|
||
|
arrays[Mesh.ARRAY_COLOR] = colors
|
||
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLES, arrays)
|
||
|
return mesh
|
||
|
|
||
|
|
||
|
|
||
|
#----------------------------------------------------------------------------------------------------------------------------------------------
|
||
|
# Text UVs
|
||
|
|
||
|
# Old dynamic code:
|
||
|
#var text_UV_arrays := []
|
||
|
#func make_text_UV(row: int, column: int) -> PoolVector2Array:
|
||
|
# return PoolVector2Array([Vector2(column/4.0, row/8.0), Vector2((column+1)/4.0, row/8.0), Vector2(column/4.0, (row+1)/8.0), Vector2((column+1)/4.0, (row+1)/8.0)])
|
||
|
#func make_text_UVs():
|
||
|
# for row in 8:
|
||
|
# for column in 4:
|
||
|
# text_UV_arrays.append(make_text_UV(row, column))
|
||
|
|
||
|
# This is replaced by a quick hacky python codegen:
|
||
|
#>>> def make_text_UV(row, column):
|
||
|
#... return f'PoolVector2Array([Vector2({column}/4.0, {row}/8.0), Vector2({column+1}/4.0, {row}/8.0), Vector2({column}/4.0, {row+1}/8.0), Vector2({column+1}/4.0, {row+1}/8.0)])'
|
||
|
#>>> for row in range(8):
|
||
|
#... for col in range(4):
|
||
|
#... print(make_text_UV(row, col) + ',')
|
||
|
|
||
|
const text_UV_arrays := [
|
||
|
PoolVector2Array([Vector2(0/4.0, 0/8.0), Vector2(1/4.0, 0/8.0), Vector2(0/4.0, 1/8.0), Vector2(1/4.0, 1/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 0/8.0), Vector2(2/4.0, 0/8.0), Vector2(1/4.0, 1/8.0), Vector2(2/4.0, 1/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 0/8.0), Vector2(3/4.0, 0/8.0), Vector2(2/4.0, 1/8.0), Vector2(3/4.0, 1/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 0/8.0), Vector2(4/4.0, 0/8.0), Vector2(3/4.0, 1/8.0), Vector2(4/4.0, 1/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 1/8.0), Vector2(1/4.0, 1/8.0), Vector2(0/4.0, 2/8.0), Vector2(1/4.0, 2/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 1/8.0), Vector2(2/4.0, 1/8.0), Vector2(1/4.0, 2/8.0), Vector2(2/4.0, 2/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 1/8.0), Vector2(3/4.0, 1/8.0), Vector2(2/4.0, 2/8.0), Vector2(3/4.0, 2/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 1/8.0), Vector2(4/4.0, 1/8.0), Vector2(3/4.0, 2/8.0), Vector2(4/4.0, 2/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 2/8.0), Vector2(1/4.0, 2/8.0), Vector2(0/4.0, 3/8.0), Vector2(1/4.0, 3/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 2/8.0), Vector2(2/4.0, 2/8.0), Vector2(1/4.0, 3/8.0), Vector2(2/4.0, 3/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 2/8.0), Vector2(3/4.0, 2/8.0), Vector2(2/4.0, 3/8.0), Vector2(3/4.0, 3/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 2/8.0), Vector2(4/4.0, 2/8.0), Vector2(3/4.0, 3/8.0), Vector2(4/4.0, 3/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 3/8.0), Vector2(1/4.0, 3/8.0), Vector2(0/4.0, 4/8.0), Vector2(1/4.0, 4/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 3/8.0), Vector2(2/4.0, 3/8.0), Vector2(1/4.0, 4/8.0), Vector2(2/4.0, 4/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 3/8.0), Vector2(3/4.0, 3/8.0), Vector2(2/4.0, 4/8.0), Vector2(3/4.0, 4/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 3/8.0), Vector2(4/4.0, 3/8.0), Vector2(3/4.0, 4/8.0), Vector2(4/4.0, 4/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 4/8.0), Vector2(1/4.0, 4/8.0), Vector2(0/4.0, 5/8.0), Vector2(1/4.0, 5/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 4/8.0), Vector2(2/4.0, 4/8.0), Vector2(1/4.0, 5/8.0), Vector2(2/4.0, 5/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 4/8.0), Vector2(3/4.0, 4/8.0), Vector2(2/4.0, 5/8.0), Vector2(3/4.0, 5/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 4/8.0), Vector2(4/4.0, 4/8.0), Vector2(3/4.0, 5/8.0), Vector2(4/4.0, 5/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 5/8.0), Vector2(1/4.0, 5/8.0), Vector2(0/4.0, 6/8.0), Vector2(1/4.0, 6/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 5/8.0), Vector2(2/4.0, 5/8.0), Vector2(1/4.0, 6/8.0), Vector2(2/4.0, 6/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 5/8.0), Vector2(3/4.0, 5/8.0), Vector2(2/4.0, 6/8.0), Vector2(3/4.0, 6/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 5/8.0), Vector2(4/4.0, 5/8.0), Vector2(3/4.0, 6/8.0), Vector2(4/4.0, 6/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 6/8.0), Vector2(1/4.0, 6/8.0), Vector2(0/4.0, 7/8.0), Vector2(1/4.0, 7/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 6/8.0), Vector2(2/4.0, 6/8.0), Vector2(1/4.0, 7/8.0), Vector2(2/4.0, 7/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 6/8.0), Vector2(3/4.0, 6/8.0), Vector2(2/4.0, 7/8.0), Vector2(3/4.0, 7/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 6/8.0), Vector2(4/4.0, 6/8.0), Vector2(3/4.0, 7/8.0), Vector2(4/4.0, 7/8.0)]),
|
||
|
PoolVector2Array([Vector2(0/4.0, 7/8.0), Vector2(1/4.0, 7/8.0), Vector2(0/4.0, 8/8.0), Vector2(1/4.0, 8/8.0)]),
|
||
|
PoolVector2Array([Vector2(1/4.0, 7/8.0), Vector2(2/4.0, 7/8.0), Vector2(1/4.0, 8/8.0), Vector2(2/4.0, 8/8.0)]),
|
||
|
PoolVector2Array([Vector2(2/4.0, 7/8.0), Vector2(3/4.0, 7/8.0), Vector2(2/4.0, 8/8.0), Vector2(3/4.0, 8/8.0)]),
|
||
|
PoolVector2Array([Vector2(3/4.0, 7/8.0), Vector2(4/4.0, 7/8.0), Vector2(3/4.0, 8/8.0), Vector2(4/4.0, 8/8.0)])
|
||
|
]
|
||
|
|
||
|
enum TextStyle {STRAIGHT=0, ARC=1, ARC_EARLY=2, ARC_LATE=3}
|
||
|
enum TextWord {NICE=0, OK=4, NG=8, PERFECT=12, GREAT=16, GOOD=20, ALMOST=24, MISS=28}
|
||
|
const TextJudgement := {
|
||
|
0: TextWord.PERFECT + TextStyle.ARC,
|
||
|
1: TextWord.GREAT + TextStyle.ARC_LATE,
|
||
|
-1: TextWord.GREAT + TextStyle.ARC_EARLY,
|
||
|
2: TextWord.GOOD + TextStyle.ARC_LATE,
|
||
|
-2: TextWord.GOOD + TextStyle.ARC_EARLY,
|
||
|
3: TextWord.ALMOST + TextStyle.ARC_LATE,
|
||
|
-3: TextWord.ALMOST + TextStyle.ARC_EARLY,
|
||
|
'MISS': TextWord.MISS + TextStyle.ARC
|
||
|
}
|
||
|
const TextJudgementStraight := {
|
||
|
0: TextWord.PERFECT + TextStyle.STRAIGHT,
|
||
|
1: TextWord.GREAT + TextStyle.STRAIGHT,
|
||
|
-1: TextWord.GREAT + TextStyle.STRAIGHT,
|
||
|
2: TextWord.GOOD + TextStyle.STRAIGHT,
|
||
|
-2: TextWord.GOOD + TextStyle.STRAIGHT,
|
||
|
3: TextWord.ALMOST + TextStyle.STRAIGHT,
|
||
|
-3: TextWord.ALMOST + TextStyle.STRAIGHT,
|
||
|
'MISS': TextWord.MISS + TextStyle.STRAIGHT
|
||
|
}
|
||
|
|
||
|
static func make_text_mesh(mesh: ArrayMesh, text_id: int, pos: Vector2, angle: float, alpha:=1.0, scale:=1.0):
|
||
|
var r := GameTheme.judge_text_size2 * scale
|
||
|
var vertex_array := PoolVector2Array([
|
||
|
pos+polar2cartesian(r, angle+GameTheme.JUDGE_TEXT_ANG2), # TODO: fix this UV/vertex order mess
|
||
|
pos+polar2cartesian(r, angle+GameTheme.JUDGE_TEXT_ANG1),
|
||
|
pos+polar2cartesian(r, angle+GameTheme.JUDGE_TEXT_ANG4),
|
||
|
pos+polar2cartesian(r, angle+GameTheme.JUDGE_TEXT_ANG3)
|
||
|
])
|
||
|
var arrays = []
|
||
|
arrays.resize(Mesh.ARRAY_MAX)
|
||
|
arrays[Mesh.ARRAY_VERTEX] = vertex_array
|
||
|
arrays[Mesh.ARRAY_TEX_UV] = text_UV_arrays[text_id]
|
||
|
arrays[Mesh.ARRAY_COLOR] = GameTheme.color_array_text(alpha)
|
||
|
mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays)
|
||
|
|
||
|
static func make_judgement_text(mesh: ArrayMesh, text_id: int, col: int, progress:=0.0):
|
||
|
make_text_mesh(mesh, text_id,
|
||
|
GameTheme.RADIAL_UNIT_VECTORS[col] * GameTheme.receptor_ring_radius * lerp(0.85, 0.85*0.75, progress),
|
||
|
GameTheme.RADIAL_COL_ANGLES[col]-PI/2.0, lerp(1.0, 0.0, progress), lerp(1.0, 0.75, progress)
|
||
|
)
|
||
|
|