Unknown WIP refactoring over the years
This commit is contained in:
parent
d45a4ae0fa
commit
67f48fd0dc
|
@ -28,6 +28,7 @@ process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/HDR_as_SRGB=false
|
process/HDR_as_SRGB=false
|
||||||
process/invert_color=false
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
stream=false
|
stream=false
|
||||||
size_limit=0
|
size_limit=0
|
||||||
detect_3d=true
|
detect_3d=true
|
||||||
|
|
|
@ -28,6 +28,7 @@ process/fix_alpha_border=true
|
||||||
process/premult_alpha=false
|
process/premult_alpha=false
|
||||||
process/HDR_as_SRGB=false
|
process/HDR_as_SRGB=false
|
||||||
process/invert_color=false
|
process/invert_color=false
|
||||||
|
process/normal_map_invert_y=false
|
||||||
stream=false
|
stream=false
|
||||||
size_limit=0
|
size_limit=0
|
||||||
detect_3d=true
|
detect_3d=true
|
||||||
|
|
|
@ -2,6 +2,12 @@
|
||||||
|
|
||||||
[ext_resource path="res://assets/fonts/Sniglet-Regular.ttf" type="DynamicFontData" id=1]
|
[ext_resource path="res://assets/fonts/Sniglet-Regular.ttf" type="DynamicFontData" id=1]
|
||||||
|
|
||||||
|
[sub_resource type="DynamicFont" id=1]
|
||||||
|
size = 48
|
||||||
|
outline_size = 4
|
||||||
|
outline_color = Color( 0, 0, 0, 1 )
|
||||||
|
font_data = ExtResource( 1 )
|
||||||
|
|
||||||
[sub_resource type="StyleBoxFlat" id=3]
|
[sub_resource type="StyleBoxFlat" id=3]
|
||||||
content_margin_left = 24.0
|
content_margin_left = 24.0
|
||||||
content_margin_right = 24.0
|
content_margin_right = 24.0
|
||||||
|
@ -69,12 +75,6 @@ corner_radius_bottom_left = 16
|
||||||
shadow_color = Color( 0.423529, 0.670588, 1, 0.372549 )
|
shadow_color = Color( 0.423529, 0.670588, 1, 0.372549 )
|
||||||
shadow_size = 6
|
shadow_size = 6
|
||||||
|
|
||||||
[sub_resource type="DynamicFont" id=1]
|
|
||||||
size = 48
|
|
||||||
outline_size = 4
|
|
||||||
outline_color = Color( 0, 0, 0, 1 )
|
|
||||||
font_data = ExtResource( 1 )
|
|
||||||
|
|
||||||
[resource]
|
[resource]
|
||||||
default_font = SubResource( 1 )
|
default_font = SubResource( 1 )
|
||||||
Button/colors/font_color = Color( 0.88, 0.88, 0.88, 1 )
|
Button/colors/font_color = Color( 0.88, 0.88, 0.88, 1 )
|
||||||
|
@ -82,7 +82,7 @@ Button/colors/font_color_disabled = Color( 0.9, 0.9, 0.9, 0.2 )
|
||||||
Button/colors/font_color_hover = Color( 0.827451, 0.788235, 1, 1 )
|
Button/colors/font_color_hover = Color( 0.827451, 0.788235, 1, 1 )
|
||||||
Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
|
Button/colors/font_color_pressed = Color( 1, 1, 1, 1 )
|
||||||
Button/constants/hseparation = 2
|
Button/constants/hseparation = 2
|
||||||
Button/fonts/font = null
|
Button/fonts/font = SubResource( 1 )
|
||||||
Button/styles/disabled = SubResource( 3 )
|
Button/styles/disabled = SubResource( 3 )
|
||||||
Button/styles/focus = SubResource( 4 )
|
Button/styles/focus = SubResource( 4 )
|
||||||
Button/styles/hover = SubResource( 2 )
|
Button/styles/hover = SubResource( 2 )
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
extends Control
|
extends Control
|
||||||
var RadialMeshTools := preload('res://scripts/RadialMeshTools.gd')
|
const RadialMeshTools := preload('res://scripts/RadialMeshTools.gd')
|
||||||
|
|
||||||
var screen_height := 1080
|
var screen_height := 1080
|
||||||
|
|
||||||
|
@ -164,93 +164,105 @@ func check_hold_release(col):
|
||||||
do_hold_release(note) # Separate function since there's no need to 'consume' releases
|
do_hold_release(note) # Separate function since there's no need to 'consume' releases
|
||||||
|
|
||||||
#----------------------------------------------------------------------------------------------------------------------------------------------
|
#----------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
const arr_div := Vector3(2.0, float(Rules.COLS), TAU)
|
func draw_note(mesh, note, position, t):
|
||||||
|
var output = null
|
||||||
|
var scale := 1.0
|
||||||
|
|
||||||
|
if position < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
||||||
|
scale *= position/GameTheme.INNER_NOTE_CIRCLE_RATIO
|
||||||
|
position = GameTheme.INNER_NOTE_CIRCLE_RATIO
|
||||||
|
|
||||||
|
var note_center = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position * GameTheme.receptor_ring_radius)
|
||||||
|
var color: PoolColorArray
|
||||||
|
|
||||||
|
match note.type:
|
||||||
|
Note.NOTE_TAP:
|
||||||
|
color = GameTheme.color_array_tap(clamp((note.time_death-t)/Note.DEATH_DELAY, 0.0, 1.0), note.double_hit)
|
||||||
|
RadialMeshTools.make_tap_mesh(mesh, note_center, scale, color)
|
||||||
|
|
||||||
|
Note.NOTE_STAR:
|
||||||
|
color = GameTheme.color_array_star(clamp((note.time_death-t)/Note.DEATH_DELAY, 0.0, 1.0), note.double_hit)
|
||||||
|
var angle = fmod(t/note.duration, 1.0)*TAU
|
||||||
|
RadialMeshTools.make_star_mesh(mesh, note_center, scale, angle, color)
|
||||||
|
|
||||||
|
Note.NOTE_HOLD:
|
||||||
|
if note.is_held:
|
||||||
|
position = (t+GameTheme.note_forecast_beats-note.time_release)/GameTheme.note_forecast_beats
|
||||||
|
color = GameTheme.COLOR_ARRAY_HOLD_HELD
|
||||||
|
note_center = GameTheme.RADIAL_UNIT_VECTORS[note.column] * GameTheme.receptor_ring_radius * max(position, 1.0)
|
||||||
|
elif position > 1.0:
|
||||||
|
color = GameTheme.COLOR_ARRAY_DOUBLE_MISS_8 if note.double_hit else GameTheme.COLOR_ARRAY_HOLD_MISS
|
||||||
|
if note.time_released != INF:
|
||||||
|
position = (t+GameTheme.note_forecast_beats-note.time_released)/GameTheme.note_forecast_beats
|
||||||
|
note_center = GameTheme.RADIAL_UNIT_VECTORS[note.column] * GameTheme.receptor_ring_radius * position
|
||||||
|
else:
|
||||||
|
color = GameTheme.COLOR_ARRAY_DOUBLE_8 if note.double_hit else GameTheme.COLOR_ARRAY_HOLD
|
||||||
|
var position_rel : float = (t+GameTheme.note_forecast_beats-note.time_release)/GameTheme.note_forecast_beats
|
||||||
|
if position_rel > 0:
|
||||||
|
var note_rel_center := (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position_rel * GameTheme.receptor_ring_radius)
|
||||||
|
output = [position_rel, note.column]
|
||||||
|
if position_rel < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
||||||
|
position_rel = GameTheme.INNER_NOTE_CIRCLE_RATIO
|
||||||
|
var note_center_rel = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position_rel * GameTheme.receptor_ring_radius)
|
||||||
|
RadialMeshTools.make_hold_mesh(mesh, note_center, note_center_rel, scale, GameTheme.RADIAL_COL_ANGLES[note.column], color)
|
||||||
|
|
||||||
|
Note.NOTE_SLIDE:
|
||||||
|
var trail_alpha := 1.0
|
||||||
|
if position < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
||||||
|
trail_alpha = 0.0
|
||||||
|
elif position < 1.0:
|
||||||
|
trail_alpha = min(1.0, (position-GameTheme.INNER_NOTE_CIRCLE_RATIO)/(1-GameTheme.INNER_NOTE_CIRCLE_RATIO*2))
|
||||||
|
else:
|
||||||
|
var trail_progress : float = clamp((t - note.time_hit - GameTheme.SLIDE_DELAY)/(note.duration - GameTheme.SLIDE_DELAY), 0.0, 1.0)
|
||||||
|
var star_pos : Vector2 = note.get_position(trail_progress) * GameTheme.receptor_ring_radius
|
||||||
|
var star_angle : float = note.get_angle(trail_progress)
|
||||||
|
RadialMeshTools.make_star_mesh(mesh, star_pos, 1.33, star_angle)
|
||||||
|
if note.progress != INF:
|
||||||
|
slide_trail_mesh_instances[note.slide_id].material.set_shader_param('trail_progress', note.progress)
|
||||||
|
if t > note.time_release:
|
||||||
|
trail_alpha = max(1 - (t - note.time_release)/Note.DEATH_DELAY, 0.0)
|
||||||
|
slide_trail_mesh_instances[note.slide_id].material.set_shader_param('base_alpha', trail_alpha*GameTheme.slide_trail_alpha) # TODO: somehow factor this out?
|
||||||
|
|
||||||
|
return output
|
||||||
|
|
||||||
|
|
||||||
|
#----------------------------------------------------------------------------------------------------------------------------------------------
|
||||||
|
const arr_div := Vector3(2.0, float(Rules.COLS), TAU) # Scaling factors to avoid LDR processing clipping our values
|
||||||
func _draw():
|
func _draw():
|
||||||
var mesh := ArrayMesh.new()
|
var mesh := ArrayMesh.new()
|
||||||
var noteline_data : Image = noteline_array_image.get_rect(Rect2(0, 0, 16, 16))
|
var hit_spots := []
|
||||||
noteline_data.lock()
|
var release_spots := []
|
||||||
var i := 0
|
|
||||||
var j := 0
|
|
||||||
|
|
||||||
for note in active_notes:
|
for note in active_notes:
|
||||||
var position : float = (t+GameTheme.note_forecast_beats-note.time_hit)/GameTheme.note_forecast_beats
|
var position : float = (t+GameTheme.note_forecast_beats-note.time_hit)/GameTheme.note_forecast_beats
|
||||||
var scale := 1.0
|
|
||||||
|
|
||||||
if note.hittable:
|
if note.hittable:
|
||||||
noteline_data.set_pixel(
|
hit_spots.append([position, note.column])
|
||||||
i%16, i/16, Color(
|
var release = draw_note(mesh, note, position, t)
|
||||||
position/arr_div.x,
|
if release:
|
||||||
float(note.column)/arr_div.y,
|
release_spots.append([position, note.column])
|
||||||
GameTheme.RADIAL_COL_ANGLES[note.column]/arr_div.z
|
|
||||||
)
|
|
||||||
)
|
|
||||||
i += 1
|
|
||||||
|
|
||||||
if position < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
# In the absense of shader uniform arrays, we have to send our data via a texture
|
||||||
scale *= position/GameTheme.INNER_NOTE_CIRCLE_RATIO
|
var noteline_data : Image = noteline_array_image.get_rect(Rect2(0, 0, 16, 16))
|
||||||
position = GameTheme.INNER_NOTE_CIRCLE_RATIO
|
|
||||||
|
|
||||||
var note_center = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position * GameTheme.receptor_ring_radius)
|
|
||||||
var color: PoolColorArray
|
|
||||||
match note.type:
|
|
||||||
Note.NOTE_TAP:
|
|
||||||
color = GameTheme.color_array_tap(clamp((note.time_death-t)/Note.DEATH_DELAY, 0.0, 1.0), note.double_hit)
|
|
||||||
RadialMeshTools.make_tap_mesh(mesh, note_center, scale, color)
|
|
||||||
Note.NOTE_STAR:
|
|
||||||
color = GameTheme.color_array_star(clamp((note.time_death-t)/Note.DEATH_DELAY, 0.0, 1.0), note.double_hit)
|
|
||||||
var angle = fmod(t/note.duration, 1.0)*TAU
|
|
||||||
RadialMeshTools.make_star_mesh(mesh, note_center, scale, angle, color)
|
|
||||||
Note.NOTE_HOLD:
|
|
||||||
if note.is_held:
|
|
||||||
position = (t+GameTheme.note_forecast_beats-note.time_release)/GameTheme.note_forecast_beats
|
|
||||||
color = GameTheme.COLOR_ARRAY_HOLD_HELD
|
|
||||||
note_center = GameTheme.RADIAL_UNIT_VECTORS[note.column] * GameTheme.receptor_ring_radius * max(position, 1.0)
|
|
||||||
elif position > 1.0:
|
|
||||||
color = GameTheme.COLOR_ARRAY_DOUBLE_MISS_8 if note.double_hit else GameTheme.COLOR_ARRAY_HOLD_MISS
|
|
||||||
if note.time_released != INF:
|
|
||||||
position = (t+GameTheme.note_forecast_beats-note.time_released)/GameTheme.note_forecast_beats
|
|
||||||
note_center = GameTheme.RADIAL_UNIT_VECTORS[note.column] * GameTheme.receptor_ring_radius * position
|
|
||||||
else:
|
|
||||||
color = GameTheme.COLOR_ARRAY_DOUBLE_8 if note.double_hit else GameTheme.COLOR_ARRAY_HOLD
|
|
||||||
var position_rel : float = (t+GameTheme.note_forecast_beats-note.time_release)/GameTheme.note_forecast_beats
|
|
||||||
if position_rel > 0:
|
|
||||||
var note_rel_center := (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position_rel * GameTheme.receptor_ring_radius)
|
|
||||||
noteline_data.set_pixel(
|
|
||||||
j%16, 15, Color(
|
|
||||||
position_rel/arr_div.x,
|
|
||||||
float(note.column)/arr_div.y,
|
|
||||||
GameTheme.RADIAL_COL_ANGLES[note.column]/arr_div.z
|
|
||||||
)
|
|
||||||
)
|
|
||||||
j += 1
|
|
||||||
if position_rel < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
|
||||||
position_rel = GameTheme.INNER_NOTE_CIRCLE_RATIO
|
|
||||||
var note_center_rel = (GameTheme.RADIAL_UNIT_VECTORS[note.column] * position_rel * GameTheme.receptor_ring_radius)
|
|
||||||
RadialMeshTools.make_hold_mesh(mesh, note_center, note_center_rel, scale, GameTheme.RADIAL_COL_ANGLES[note.column], color)
|
|
||||||
Note.NOTE_SLIDE:
|
|
||||||
var trail_alpha := 1.0
|
|
||||||
if position < GameTheme.INNER_NOTE_CIRCLE_RATIO:
|
|
||||||
trail_alpha = 0.0
|
|
||||||
elif position < 1.0:
|
|
||||||
trail_alpha = min(1.0, (position-GameTheme.INNER_NOTE_CIRCLE_RATIO)/(1-GameTheme.INNER_NOTE_CIRCLE_RATIO*2))
|
|
||||||
else:
|
|
||||||
var trail_progress : float = clamp((t - note.time_hit - GameTheme.SLIDE_DELAY)/(note.duration - GameTheme.SLIDE_DELAY), 0.0, 1.0)
|
|
||||||
var star_pos : Vector2 = note.get_position(trail_progress) * GameTheme.receptor_ring_radius
|
|
||||||
var star_angle : float = note.get_angle(trail_progress)
|
|
||||||
RadialMeshTools.make_star_mesh(mesh, star_pos, 1.33, star_angle)
|
|
||||||
if note.progress != INF:
|
|
||||||
slide_trail_mesh_instances[note.slide_id].material.set_shader_param('trail_progress', note.progress)
|
|
||||||
if t > note.time_release:
|
|
||||||
trail_alpha = max(1 - (t - note.time_release)/Note.DEATH_DELAY, 0.0)
|
|
||||||
slide_trail_mesh_instances[note.slide_id].material.set_shader_param('base_alpha', trail_alpha*GameTheme.slide_trail_alpha)
|
|
||||||
|
|
||||||
|
noteline_data.lock()
|
||||||
|
var i := 0
|
||||||
|
for spot in hit_spots:
|
||||||
|
noteline_data.set_pixel(i%16, i/16, Color(spot[0]/arr_div.x, float(spot[1])/arr_div.y, GameTheme.RADIAL_COL_ANGLES[spot[1]]/arr_div.z))
|
||||||
|
i += 1
|
||||||
|
i = 0
|
||||||
|
for spot in release_spots:
|
||||||
|
noteline_data.set_pixel(i%16, 15, Color(spot[0]/arr_div.x, float(spot[1])/arr_div.y, GameTheme.RADIAL_COL_ANGLES[spot[1]]/arr_div.z))
|
||||||
|
i += 1
|
||||||
noteline_data.unlock()
|
noteline_data.unlock()
|
||||||
|
|
||||||
var noteline_data_tex := ImageTexture.new()
|
var noteline_data_tex := ImageTexture.new()
|
||||||
noteline_data_tex.create_from_image(noteline_data, 0)
|
noteline_data_tex.create_from_image(noteline_data, 0)
|
||||||
notelines.set_texture(noteline_data_tex)
|
notelines.set_texture(noteline_data_tex)
|
||||||
|
|
||||||
|
# The mesh that we've added all our note vertices and UVs to
|
||||||
meshinstance.set_mesh(mesh)
|
meshinstance.set_mesh(mesh)
|
||||||
|
|
||||||
|
# Another mesh for judgement texts
|
||||||
var textmesh := ArrayMesh.new()
|
var textmesh := ArrayMesh.new()
|
||||||
for text in active_judgement_texts:
|
for text in active_judgement_texts:
|
||||||
RadialMeshTools.make_judgement_text(textmesh, RadialMeshTools.TextJudgement[text.judgement], text.col, (t-text.time)/GameTheme.judge_text_duration)
|
RadialMeshTools.make_judgement_text(textmesh, RadialMeshTools.TextJudgement[text.judgement], text.col, (t-text.time)/GameTheme.judge_text_duration)
|
||||||
|
@ -288,12 +300,14 @@ func _init():
|
||||||
GameTheme.init_radial_values()
|
GameTheme.init_radial_values()
|
||||||
initialise_scores()
|
initialise_scores()
|
||||||
|
|
||||||
|
|
||||||
func set_time(seconds: float):
|
func set_time(seconds: float):
|
||||||
var msecs = OS.get_ticks_msec()
|
var msecs = OS.get_ticks_msec()
|
||||||
time_zero_msec = msecs - (seconds * 1000)
|
time_zero_msec = msecs - (seconds * 1000)
|
||||||
time = seconds
|
time = seconds
|
||||||
t = game_time(time)
|
t = game_time(time)
|
||||||
|
|
||||||
|
|
||||||
func make_noteline_mesh(vertices := 32) -> ArrayMesh:
|
func make_noteline_mesh(vertices := 32) -> ArrayMesh:
|
||||||
assert(vertices > 3)
|
assert(vertices > 3)
|
||||||
var rec_scale1 = (float(screen_height)/float(GameTheme.receptor_ring_radius))*0.5
|
var rec_scale1 = (float(screen_height)/float(GameTheme.receptor_ring_radius))*0.5
|
||||||
|
@ -318,6 +332,7 @@ func make_noteline_mesh(vertices := 32) -> ArrayMesh:
|
||||||
mesh_playfield.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_FAN, arrays)
|
mesh_playfield.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_FAN, arrays)
|
||||||
return mesh_playfield
|
return mesh_playfield
|
||||||
|
|
||||||
|
|
||||||
# Called when the node enters the scene tree for the first time.
|
# Called when the node enters the scene tree for the first time.
|
||||||
func _ready():
|
func _ready():
|
||||||
notelines.set_mesh(make_noteline_mesh())
|
notelines.set_mesh(make_noteline_mesh())
|
||||||
|
@ -334,6 +349,7 @@ func _ready():
|
||||||
meshinstance.material.set_shader_param('screen_size', get_viewport().get_size())
|
meshinstance.material.set_shader_param('screen_size', get_viewport().get_size())
|
||||||
meshinstance.set_texture(GameTheme.tex_notes)
|
meshinstance.set_texture(GameTheme.tex_notes)
|
||||||
|
|
||||||
|
|
||||||
func load_track(song_key: String, difficulty_key: String):
|
func load_track(song_key: String, difficulty_key: String):
|
||||||
self.song_key = song_key
|
self.song_key = song_key
|
||||||
set_time(-3.0)
|
set_time(-3.0)
|
||||||
|
@ -360,31 +376,39 @@ func load_track(song_key: String, difficulty_key: String):
|
||||||
|
|
||||||
initialise_scores() # Remove old score
|
initialise_scores() # Remove old score
|
||||||
|
|
||||||
|
|
||||||
func stop():
|
func stop():
|
||||||
MusicPlayer.stop()
|
MusicPlayer.stop()
|
||||||
VideoPlayer.stop()
|
VideoPlayer.stop()
|
||||||
# running = false
|
# running = false
|
||||||
next_note_to_load = 10000000 # Hacky but whatever
|
next_note_to_load = 10000000 # Hacky but whatever
|
||||||
|
|
||||||
|
|
||||||
func intro_click():
|
func intro_click():
|
||||||
SoundPlayer.play(SoundPlayer.Type.NON_POSITIONAL, self, GameTheme.snd_count_in)
|
SoundPlayer.play(SoundPlayer.Type.NON_POSITIONAL, self, GameTheme.snd_count_in)
|
||||||
|
|
||||||
|
|
||||||
func get_realtime_precise() -> float:
|
func get_realtime_precise() -> float:
|
||||||
# Usually we only update the gametime once per process loop, but for input callbacks it's good to have msec precision
|
# Usually we only update the gametime once per process loop, but for input callbacks it's good to have msec precision
|
||||||
return (OS.get_ticks_msec() - time_zero_msec)/1000.0
|
return (OS.get_ticks_msec() - time_zero_msec)/1000.0
|
||||||
|
|
||||||
|
|
||||||
func game_time(realtime: float) -> float:
|
func game_time(realtime: float) -> float:
|
||||||
return realtime * bpm / 60.0
|
return realtime * bpm / 60.0
|
||||||
|
|
||||||
|
|
||||||
func real_time(gametime: float) -> float:
|
func real_time(gametime: float) -> float:
|
||||||
return gametime * 60.0 / bpm
|
return gametime * 60.0 / bpm
|
||||||
|
|
||||||
|
|
||||||
func video_start_time() -> float:
|
func video_start_time() -> float:
|
||||||
return -sync_offset_video
|
return -sync_offset_video
|
||||||
|
|
||||||
|
|
||||||
func audio_start_time() -> float:
|
func audio_start_time() -> float:
|
||||||
return -sync_offset_audio
|
return -sync_offset_audio
|
||||||
|
|
||||||
|
|
||||||
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
# Called every frame. 'delta' is the elapsed time since the previous frame.
|
||||||
var timers_set := false
|
var timers_set := false
|
||||||
func _process(delta):
|
func _process(delta):
|
||||||
|
|
Loading…
Reference in New Issue