From f54171ad0b239eaa623812ba32eaa72f6ab5e2cb Mon Sep 17 00:00:00 2001 From: Luke Hubmayer-Werner Date: Thu, 14 Nov 2019 22:27:30 +1030 Subject: [PATCH] Fixed note dot regression. Slide trails are now how I want them. --- FileLoader.gd | 10 +- Note.gd | 77 +++++++++++++++- NoteHandler.gd | 198 ++++++++++++++++------------------------ Receptors.gd | 4 + main.tscn | 2 +- shaders/notemesh.shader | 18 ++-- theme.gd | 11 +++ 7 files changed, 186 insertions(+), 134 deletions(-) diff --git a/FileLoader.gd b/FileLoader.gd index f13ae6e..74a1621 100644 --- a/FileLoader.gd +++ b/FileLoader.gd @@ -38,6 +38,7 @@ class SRT: # id2 is slide ID if id2 in slide_idxs: notes[slide_idxs[id2]].column_release = column + notes[slide_idxs[id2]].update_slide_variables() _: if id2 == 0: notes.push_back(Note.make_tap(time_hit, column)) @@ -45,16 +46,17 @@ class SRT: # id2 is slide ID, id3 is slide pattern # In order to properly declare the slide, we need the paired endcap which may not be the next note slide_idxs[id2] = len(notes) - notes.push_back(Note.make_slide(time_hit, duration, column, -1)) + var slide_type = Note.SlideType.CHORD match id3: ID3_SLIDE_CHORD: - notes[slide_idxs[id2]].slide_type = Note.SlideType.CHORD + slide_type = Note.SlideType.CHORD ID3_SLIDE_ARC_CW: - notes[slide_idxs[id2]].slide_type = Note.SlideType.ARC_CW + slide_type = Note.SlideType.ARC_CW ID3_SLIDE_ARC_ACW: - notes[slide_idxs[id2]].slide_type = Note.SlideType.ARC_ACW + slide_type = Note.SlideType.ARC_ACW _: print("Unknown slide type: ", id3) + notes.push_back(Note.NoteSlide.new(time_hit, duration, column, -1, slide_type)) return notes diff --git a/Note.gd b/Note.gd index a9f10b4..6b40aac 100644 --- a/Note.gd +++ b/Note.gd @@ -7,6 +7,73 @@ enum {NOTE_TAP, NOTE_HOLD, NOTE_SLIDE, NOTE_ARROW, NOTE_TOUCH, NOTE_TOUCH_HOLD} enum SlideType {CHORD, ARC_CW, ARC_ACW} const DEATH_DELAY := 0.45 +class NoteBase: + var time_hit: float + var time_death: float + var column: int + var double_hit := false + +class NoteSlide extends NoteBase: + var type := NOTE_SLIDE + var time_release: float + var duration: float + var column_release: int + var slide_type: int + var slide_id: int + var values: Dictionary + + func _init(time_hit: float, duration: float, column: int, column_release: int, slide_type: int): + self.time_hit = time_hit + self.duration = duration + self.time_release = time_hit + duration + self.time_death = time_release + DEATH_DELAY + self.column = column + self.column_release = column_release + self.slide_type = slide_type + self.values = {} + update_slide_variables() + + func update_slide_variables(): + match slide_type: + Note.SlideType.CHORD: + values.start = theme.RADIAL_UNIT_VECTORS[column] * theme.receptor_ring_radius + values.end = theme.RADIAL_UNIT_VECTORS[column_release] * theme.receptor_ring_radius + values.angle = (values.end - values.start).angle() + Note.SlideType.ARC_CW: + values.start_a = theme.RADIAL_COL_ANGLES[column] + values.end_a = theme.RADIAL_COL_ANGLES[column_release] + if values.end_a < values.start_a: + values.end_a += TAU + Note.SlideType.ARC_ACW: + values.start_a = theme.RADIAL_COL_ANGLES[column] + values.end_a = theme.RADIAL_COL_ANGLES[column_release] + if values.end_a > values.start_a: + values.end_a -= TAU + + func get_position(progress: float) -> Vector2: + match slide_type: + Note.SlideType.CHORD: + return lerp(values.start, values.end, progress) + Note.SlideType.ARC_CW: + var circle_angle : float = lerp(values.start_a, values.end_a, progress) + return polar2cartesian(theme.receptor_ring_radius, circle_angle) + Note.SlideType.ARC_ACW: + var circle_angle : float = lerp(values.start_a, values.end_a, progress) + return polar2cartesian(theme.receptor_ring_radius, circle_angle) + + func get_angle(progress: float) -> float: + match slide_type: + Note.SlideType.CHORD: + return values.angle + Note.SlideType.ARC_CW: + var circle_angle : float = lerp(values.start_a, values.end_a, progress) + return circle_angle + PI/2.0 + Note.SlideType.ARC_ACW: + var circle_angle : float = lerp(values.start_a, values.end_a, progress) + return circle_angle - PI/2.0 + + + static func make_tap(time_hit: float, column: int) -> Dictionary: return {type=NOTE_TAP, time_hit=time_hit, time_death=time_hit+DEATH_DELAY, column=column, double_hit=false} @@ -17,10 +84,11 @@ static func make_hold(time_hit: float, duration: float, column: int) -> Dictiona var time_release := time_hit + duration return {type=NOTE_HOLD, time_hit=time_hit, time_release=time_release, time_death=time_release+DEATH_DELAY, column=column, double_hit=false} -static func make_slide(time_hit: float, duration: float, column: int, column_release: int) -> Dictionary: - var time_release := time_hit + duration - return {type=NOTE_SLIDE, time_hit=time_hit, time_release=time_release, duration=duration, - time_death=time_release+DEATH_DELAY, column=column, column_release=column_release, double_hit=false} +static func make_slide(time_hit: float, duration: float, column: int, column_release: int, slide_type:=SlideType.CHORD) -> NoteSlide: +# var time_release := time_hit + duration +# return {type=NOTE_SLIDE, time_hit=time_hit, time_release=time_release, duration=duration, +# time_death=time_release+DEATH_DELAY, column=column, column_release=column_release, double_hit=false} + return NoteSlide.new(time_hit, duration, column, column_release, slide_type) static func make_touch(time_hit: float, location: Vector2) -> Dictionary: return {type=NOTE_TOUCH, time_hit=time_hit, time_death=time_hit+DEATH_DELAY, location=location, double_hit=false} @@ -45,3 +113,4 @@ static func process_note_list(note_array: Array): if note_array[i].type == NOTE_SLIDE: note_array[i].slide_id = slide_id slide_id += 1 + diff --git a/NoteHandler.gd b/NoteHandler.gd index e8b8be2..73788fd 100644 --- a/NoteHandler.gd +++ b/NoteHandler.gd @@ -6,31 +6,15 @@ var tex := preload("res://assets/spritesheet-1024.png") var tex_slide_arrow := preload("res://assets/slide-arrow-512.png") var slide_trail_shadermaterial := preload("res://shaders/slidetrail.tres") -# Constants for the overall notefield -var RADIAL_COL_ANGLES := PoolRealArray() # ideally const -var RADIAL_UNIT_VECTORS := PoolVector2Array() # ideally const - -# ------------------------------------------------------ -# Ring segments is only for CPU drawing, superceded for now. -# ------------------------------------------------------ -#const RING_LINE_SEGMENTS_PER_COLUMN := 12 -#var RING_LINE_SEGMENTS_VECTORS := PoolVector2Array() -#const ring_segs := Rules.COLS * RING_LINE_SEGMENTS_PER_COLUMN -#const ring_seg_angle := 360.0/ring_segs -#var ring_line_segments_alphas = PoolRealArray() -#var ring_line_segments_widths = PoolRealArray() -func init_radial_values(): - for i in range(Rules.COLS): - var angle = deg2rad(fmod(Rules.FIRST_COLUMN_ANGLE_DEG + (i * Rules.COLS_ANGLE_DEG), 360.0)) - RADIAL_COL_ANGLES.push_back(angle) - RADIAL_UNIT_VECTORS.push_back(Vector2(cos(angle), sin(angle))) -# for i in range(ring_segs): -# var angle = deg2rad(Rules.FIRST_COLUMN_ANGLE_DEG + (i * ring_seg_angle)) -# RING_LINE_SEGMENTS_VECTORS.push_back(Vector2(cos(angle), sin(angle))) -# for i in range(ring_segs/4): -# var alpha := 1.0 - (i/float(ring_segs/4)) -# ring_line_segments_alphas.push_back(alpha) -# ring_line_segments_widths.push_back(lerp(alpha, 1.0, 0.5)) +## Constants for the overall notefield +#var theme.RADIAL_COL_ANGLES := PoolRealArray() # ideally const +#var theme.RADIAL_UNIT_VECTORS := PoolVector2Array() # ideally const +# +#func init_radial_values(): +# for i in range(Rules.COLS): +# var angle = deg2rad(fmod(Rules.FIRST_COLUMN_ANGLE_DEG + (i * Rules.COLS_ANGLE_DEG), 360.0)) +# theme.RADIAL_COL_ANGLES.push_back(angle) +# theme.RADIAL_UNIT_VECTORS.push_back(Vector2(cos(angle), sin(angle))) const SQRT2 := sqrt(2) const DEG45 := deg2rad(45.0) @@ -72,7 +56,9 @@ var NORMAL_ARRAY_8 := PoolVector3Array([ # ---------------------------------------------------------------------------------------------------------------------------------------------------- # Helper functions to generate meshes from vertex arrays -func make_tap_mesh(mesh: ArrayMesh, vertex_array, color_array = theme.COLOR_ARRAY_TAP): +func make_tap_mesh(mesh: ArrayMesh, note_center: Vector2, scale:=1.0, color_array:=theme.COLOR_ARRAY_TAP): + var dim = theme.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 @@ -81,7 +67,21 @@ func make_tap_mesh(mesh: ArrayMesh, vertex_array, color_array = theme.COLOR_ARRA arrays[Mesh.ARRAY_COLOR] = color_array mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays) -func make_hold_mesh(mesh: ArrayMesh, vertex_array, color_array = theme.COLOR_ARRAY_HOLD): +func make_hold_mesh(mesh: ArrayMesh, note_center: Vector2, note_center_rel: Vector2, scale:=1.0, angle:=0.0, color_array = theme.COLOR_ARRAY_HOLD): + var dim = theme.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 @@ -90,7 +90,16 @@ func make_hold_mesh(mesh: ArrayMesh, vertex_array, color_array = theme.COLOR_ARR arrays[Mesh.ARRAY_COLOR] = color_array mesh.add_surface_from_arrays(Mesh.PRIMITIVE_TRIANGLE_STRIP, arrays) -func make_star_mesh(mesh: ArrayMesh, vertex_array, color_array = theme.COLOR_ARRAY_STAR): +func make_star_mesh(mesh: ArrayMesh, note_center: Vector2, scale:=1.0, angle:=0.0, color_array:=theme.COLOR_ARRAY_STAR): + var dim = theme.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 @@ -99,18 +108,18 @@ func make_star_mesh(mesh: ArrayMesh, vertex_array, color_array = theme.COLOR_ARR 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 = theme.COLOR_ARRAY_TAP): - var arrays = [] - arrays.resize(Mesh.ARRAY_MAX) - arrays[Mesh.ARRAY_VERTEX] = vertex_array -# arrays[Mesh.ARRAY_NORMAL] = NORMAL_ARRAY_4 - arrays[Mesh.ARRAY_TEX_UV] = UV_ARRAY_ARROW - 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 = theme.COLOR_ARRAY_TAP): +# var arrays = [] +# arrays.resize(Mesh.ARRAY_MAX) +# arrays[Mesh.ARRAY_VERTEX] = vertex_array +## arrays[Mesh.ARRAY_NORMAL] = NORMAL_ARRAY_4 +# 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 -func make_slide_trail_mesh(note: Dictionary) -> ArrayMesh: +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 = [] @@ -128,11 +137,11 @@ func make_slide_trail_mesh(note: Dictionary) -> ArrayMesh: var trail_length: int match note.slide_type: Note.SlideType.CHORD: - unit_length = 2*abs(sin((RADIAL_COL_ANGLES[note.column_release] - RADIAL_COL_ANGLES[note.column])/2)) + unit_length = 2*abs(sin((theme.RADIAL_COL_ANGLES[note.column_release] - theme.RADIAL_COL_ANGLES[note.column])/2)) Note.SlideType.ARC_CW: - unit_length = fposmod(RADIAL_COL_ANGLES[note.column_release] - RADIAL_COL_ANGLES[note.column], TAU) + unit_length = fposmod(theme.RADIAL_COL_ANGLES[note.column_release] - theme.RADIAL_COL_ANGLES[note.column], TAU) Note.SlideType.ARC_ACW: - unit_length = fposmod(RADIAL_COL_ANGLES[note.column] - RADIAL_COL_ANGLES[note.column_release], TAU) + unit_length = fposmod(theme.RADIAL_COL_ANGLES[note.column] - theme.RADIAL_COL_ANGLES[note.column_release], TAU) trail_length = int(floor(unit_length * slide_arrows_per_unit_length)) vertices.resize(3*trail_length) # uvs.resize(3*trail_length) @@ -145,8 +154,8 @@ func make_slide_trail_mesh(note: Dictionary) -> ArrayMesh: match note.slide_type: Note.SlideType.CHORD: - var start : Vector2 = RADIAL_UNIT_VECTORS[note.column] * theme.receptor_ring_radius - var end : Vector2 = RADIAL_UNIT_VECTORS[note.column_release] * theme.receptor_ring_radius + var start : Vector2 = theme.RADIAL_UNIT_VECTORS[note.column] * theme.receptor_ring_radius + var end : Vector2 = theme.RADIAL_UNIT_VECTORS[note.column_release] * theme.receptor_ring_radius var angle : float = (end-start).angle() var uv1o : Vector2 = polar2cartesian(size, angle) var uv2o : Vector2 = polar2cartesian(size, angle+PI/2.0) @@ -157,8 +166,8 @@ func make_slide_trail_mesh(note: Dictionary) -> ArrayMesh: vertices[i*3+1] = offset + uv2o vertices[i*3+2] = offset + uv3o Note.SlideType.ARC_CW: - var start_a : float = RADIAL_COL_ANGLES[note.column] - var end_a : float = RADIAL_COL_ANGLES[note.column_release] + var start_a : float = theme.RADIAL_COL_ANGLES[note.column] + var end_a : float = theme.RADIAL_COL_ANGLES[note.column_release] if end_a < start_a: end_a += TAU for i in trail_length: @@ -169,8 +178,8 @@ func make_slide_trail_mesh(note: Dictionary) -> ArrayMesh: vertices[i*3+1] = offset + polar2cartesian(size, angle+PI/2.0) vertices[i*3+2] = offset + polar2cartesian(size, angle-PI/2.0) Note.SlideType.ARC_ACW: - var start_a : float = RADIAL_COL_ANGLES[note.column] - var end_a : float = RADIAL_COL_ANGLES[note.column_release] + var start_a : float = theme.RADIAL_COL_ANGLES[note.column] + var end_a : float = theme.RADIAL_COL_ANGLES[note.column_release] if end_a > start_a: end_a -= TAU for i in trail_length: @@ -188,73 +197,14 @@ func make_slide_trail_mesh(note: Dictionary) -> ArrayMesh: return mesh - -func make_tap_note(mesh: ArrayMesh, column: int, position: float, scale := 1.0, color_array := theme.COLOR_ARRAY_TAP) -> ArrayMesh: - if position < theme.INNER_NOTE_CIRCLE_RATIO: - scale *= position/theme.INNER_NOTE_CIRCLE_RATIO - position = theme.INNER_NOTE_CIRCLE_RATIO - var note_center = screen_center + (RADIAL_UNIT_VECTORS[column] * position * theme.receptor_ring_radius) - var dim = theme.sprite_size2 * scale - var vertices = PoolVector2Array([note_center + Vector2(-dim, -dim), note_center + Vector2(dim, -dim), note_center + Vector2(-dim, dim), note_center + Vector2(dim, dim)]) - make_tap_mesh(mesh, vertices, color_array) - return mesh - -func make_hold_note(mesh: ArrayMesh, column: int, position1: float, position2: float, scale := 1.0, color_array = theme.COLOR_ARRAY_HOLD) -> ArrayMesh: - if position1 < theme.INNER_NOTE_CIRCLE_RATIO: - scale *= position1/theme.INNER_NOTE_CIRCLE_RATIO - position1 = theme.INNER_NOTE_CIRCLE_RATIO - if position2 < theme.INNER_NOTE_CIRCLE_RATIO: - position2 = theme.INNER_NOTE_CIRCLE_RATIO - var note_center1 = screen_center + (RADIAL_UNIT_VECTORS[column] * position1 * theme.receptor_ring_radius) - var note_center2 = screen_center + (RADIAL_UNIT_VECTORS[column] * position2 * theme.receptor_ring_radius) - var dim = theme.sprite_size2 * scale - var dim2 = dim * SQRT2 - var angle = RADIAL_COL_ANGLES[column] - 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 vertices = PoolVector2Array([ - note_center1 + dim2*Vector2(cos(a1), sin(a1)), note_center1 + dim2*Vector2(cos(a2), sin(a2)), - note_center1 + dim*Vector2(cos(a3), sin(a3)), note_center1 + dim*Vector2(cos(a4), sin(a4)), - note_center2 + dim*Vector2(cos(a3), sin(a3)), note_center2 + dim*Vector2(cos(a4), sin(a4)), - note_center2 + dim2*Vector2(cos(a5), sin(a5)), note_center2 + dim2*Vector2(cos(a6), sin(a6)) - ]) - make_hold_mesh(mesh, vertices, color_array) - return mesh - -func make_slide_note(mesh: ArrayMesh, column: int, position: float, speed := 1.0, scale := 1.0, color_array := theme.COLOR_ARRAY_STAR) -> ArrayMesh: - if position < theme.INNER_NOTE_CIRCLE_RATIO: - scale *= position/theme.INNER_NOTE_CIRCLE_RATIO - position = theme.INNER_NOTE_CIRCLE_RATIO - var note_center = screen_center + (RADIAL_UNIT_VECTORS[column] * position * theme.receptor_ring_radius) - var dim = theme.sprite_size2 * scale * SQRT2 - var angle = fmod(t*speed, 1.0)*TAU - var a1 = angle - DEG45 - var a2 = angle + DEG45 - var a3 = angle - DEG135 - var a4 = angle + DEG135 - var vertices = PoolVector2Array([ - note_center + dim*Vector2(cos(a1), sin(a1)), note_center + dim*Vector2(cos(a2), sin(a2)), - note_center + dim*Vector2(cos(a3), sin(a3)), note_center + dim*Vector2(cos(a4), sin(a4)) - ]) - make_star_mesh(mesh, vertices, color_array) - return mesh - - #---------------------------------------------------------------------------------------------------------------------------------------------- func _init(): Input.set_mouse_mode(Input.MOUSE_MODE_HIDDEN) - init_radial_values() + theme.init_radial_values() func _draw(): var mesh := ArrayMesh.new() -# var dots := PoolVector2Array() -# var dots_dict := {} - var noteline_data : Image = noteline_array_image.get_rect(Rect2(0, 0, 16, 16)) noteline_data.lock() var i := 0 @@ -262,23 +212,32 @@ func _draw(): for note in active_notes: var position : float = (t+theme.note_forecast_beats-note.time_hit)/theme.note_forecast_beats - noteline_data.set_pixel(i%16, i/16, Color(position, note.column, RADIAL_COL_ANGLES[note.column])) + var scale := 1.0 + noteline_data.set_pixel(i%16, i/16, Color(position, note.column, theme.RADIAL_COL_ANGLES[note.column])) i += 1 + if position < theme.INNER_NOTE_CIRCLE_RATIO: + scale *= position/theme.INNER_NOTE_CIRCLE_RATIO + position = theme.INNER_NOTE_CIRCLE_RATIO + var note_center = (theme.RADIAL_UNIT_VECTORS[note.column] * position * theme.receptor_ring_radius) match note.type: Note.NOTE_TAP: var color = theme.COLOR_ARRAY_DOUBLE_4 if note.double_hit else theme.COLOR_ARRAY_TAP - make_tap_note(mesh, note.column, position, 1, color) + make_tap_mesh(mesh, note_center, scale, color) Note.NOTE_HOLD: var color = theme.COLOR_ARRAY_DOUBLE_8 if note.double_hit else theme.COLOR_ARRAY_HOLD var position_rel : float = (t+theme.note_forecast_beats-note.time_release)/theme.note_forecast_beats if position_rel > 0: - var note_rel_center := screen_center + (RADIAL_UNIT_VECTORS[note.column] * position_rel * theme.receptor_ring_radius) - noteline_data.set_pixel(j%16, 15, Color(position_rel, note.column, RADIAL_COL_ANGLES[note.column])) + var note_rel_center := (theme.RADIAL_UNIT_VECTORS[note.column] * position_rel * theme.receptor_ring_radius) + noteline_data.set_pixel(j%16, 15, Color(position_rel, note.column, theme.RADIAL_COL_ANGLES[note.column])) j += 1 - make_hold_note(mesh, note.column, position, position_rel, 1.0, theme.COLOR_ARRAY_HOLD_HELD) + if position_rel < theme.INNER_NOTE_CIRCLE_RATIO: + position_rel = theme.INNER_NOTE_CIRCLE_RATIO + var note_center_rel = (theme.RADIAL_UNIT_VECTORS[note.column] * position_rel * theme.receptor_ring_radius) + make_hold_mesh(mesh, note_center, note_center_rel, scale, theme.RADIAL_COL_ANGLES[note.column], color) Note.NOTE_SLIDE: var color = theme.COLOR_ARRAY_DOUBLE_4 if note.double_hit else theme.COLOR_ARRAY_STAR - make_slide_note(mesh, note.column, position, 1.0, color) + var angle = fmod(t/note.duration, 1.0)*TAU + make_star_mesh(mesh, note_center, scale, angle, color) var trail_alpha := 1.0 if position < theme.INNER_NOTE_CIRCLE_RATIO: trail_alpha = 0.0 @@ -286,7 +245,10 @@ func _draw(): trail_alpha = min(1.0, (position-theme.INNER_NOTE_CIRCLE_RATIO)/(1-theme.INNER_NOTE_CIRCLE_RATIO*2)) else: var trail_progress : float = clamp((t - note.time_hit - theme.SLIDE_DELAY)/(note.duration - theme.SLIDE_DELAY), 0.0, 1.0) - slide_trail_mesh_instances[note.slide_id].material.set_shader_param("trail_progress", trail_progress) + var star_pos : Vector2 = note.get_position(trail_progress) + var star_angle : float = note.get_angle(trail_progress) + make_star_mesh(mesh, star_pos, 1.33, star_angle+PI, color) +# slide_trail_mesh_instances[note.slide_id].material.set_shader_param("trail_progress", trail_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*0.88) @@ -318,9 +280,12 @@ func _ready(): var rec_scale1 = (float(screen_height)/float(theme.receptor_ring_radius))*0.5 var uv_array_playfield := PoolVector2Array([Vector2(-1.0, -1.0)*rec_scale1, Vector2(-1.0, 1.0)*rec_scale1, Vector2(1.0, -1.0)*rec_scale1, Vector2(1.0, 1.0)*rec_scale1]) +# var vertex_array_playfield := PoolVector2Array([ +# Vector2(x_margin, screen_height), Vector2(x_margin, 0.0), +# Vector2(x_margin+screen_height, screen_height), Vector2(x_margin+screen_height, 0.0)]) var vertex_array_playfield := PoolVector2Array([ - Vector2(x_margin, screen_height), Vector2(x_margin, 0.0), - Vector2(x_margin+screen_height, screen_height), Vector2(x_margin+screen_height, 0.0)]) + Vector2(-screen_height/2.0, screen_height/2.0), Vector2(-screen_height/2.0, -screen_height/2.0), + Vector2(screen_height/2.0, screen_height/2.0), Vector2(screen_height/2.0, -screen_height/2.0)]) var mesh_playfield := ArrayMesh.new() var arrays = [] arrays.resize(Mesh.ARRAY_MAX) @@ -397,7 +362,6 @@ func _process(delta): if note.type == Note.NOTE_SLIDE: var meshi = MeshInstance2D.new() meshi.set_mesh(slide_trail_meshes[note.slide_id]) -# meshi.set_position(screen_center) meshi.set_material(slide_trail_shadermaterial.duplicate()) meshi.material.set_shader_param("trail_progress", 0.0) meshi.set_texture(tex_slide_arrow) @@ -408,7 +372,7 @@ func _process(delta): # DEBUG: Reset after all notes are done if (len(active_notes) < 1) and (next_note_to_load >= len(all_notes)) and (time > 10.0) and not get_node("/root/main/video").is_playing(): - time = -2.0 + time = -10.0 next_note_to_load = 0 # Redraw diff --git a/Receptors.gd b/Receptors.gd index 67f1d0b..b91b084 100644 --- a/Receptors.gd +++ b/Receptors.gd @@ -7,6 +7,9 @@ var shadow_color := Color.black var receptor_color := Color.blue func _draw(): + # Screen filter + draw_rect(Rect2(x_margin, 0, screen_height, screen_height), theme.screen_filter) + # Receptor ring var receptor_circle := arc_point_list(screen_center, theme.receptor_ring_radius, 0.0, 360.0, 360) var receptor_centers := arc_point_list(screen_center, theme.receptor_ring_radius, Rules.FIRST_COLUMN_ANGLE_DEG, Rules.FIRST_COLUMN_ANGLE_DEG+360.0-Rules.COLS_ANGLE_DEG, Rules.COLS) @@ -22,3 +25,4 @@ func _draw(): draw_line(receptor_circle[i], receptor_circle[i+1], receptor_color, ring_px, true) for i in range(len(receptor_centers)): draw_circle(receptor_centers[i], receptor_px/2, receptor_color) + diff --git a/main.tscn b/main.tscn index 583d73e..33a8cdc 100644 --- a/main.tscn +++ b/main.tscn @@ -52,10 +52,10 @@ __meta__ = { script = ExtResource( 4 ) [node name="NoteHandler" type="Node2D" parent="."] +position = Vector2( 960, 540 ) script = ExtResource( 5 ) [node name="SlideTrailHandler" type="Node2D" parent="NoteHandler"] -position = Vector2( 960, 540 ) [node name="notelines" type="MeshInstance2D" parent="NoteHandler"] material = SubResource( 1 ) diff --git a/shaders/notemesh.shader b/shaders/notemesh.shader index 941353c..16ef3ae 100644 --- a/shaders/notemesh.shader +++ b/shaders/notemesh.shader @@ -15,30 +15,32 @@ void fragment() { //Not sure if this helps or hurts performance //if (sample.a <= 0.0) discard; - float scale = sample.r; + float color_scale = sample.r; + float bright_scale = (sample.g+sample.b)/2.0; float dist = distance(FRAGCOORD.xy, screen_size/2.0); float dist_norm = dist*1.8 / screen_size.y; if (COLOR.rgb == star_color.rgb){ // Star ripple COLOR.rg += dist_norm*0.33; COLOR.rgb *= mix(abs(0.5-mod(TIME*bps*2.0+dist_norm, 1.0)), 1.0, 0.75); - COLOR.rgb *= scale; // Preserve black outlines + COLOR.rgb *= color_scale; // Preserve black outlines + COLOR.rgb = mix(COLOR.rgb, vec3(1.0), bright_scale); // Preserve white outlines } else if (COLOR.rgb == held_color.rgb){ // Hold note being held, flashy effects COLOR.b *= mix(2.0*abs(0.5-mod(TIME*bps*2.0+dist_norm, 1.0)), 1.0, 0.35); COLOR.g *= mix(1.0 - 2.0*abs(0.5-mod(TIME*bps*0.5+dist_norm, 1.0)), 0.0, 0.35); COLOR.r *= mix(abs(0.5-mod(TIME*bps, 1.0)), 1.0, 0.85); - if (scale < 0.1){ // Make outlines WHITE - COLOR.rgb = vec3(mix(dist_norm, abs(0.5-mod(TIME*bps*8.0, 1.0)), 0.33)); + if (color_scale < 0.5){ // Make black outlines shine + COLOR.rgb = mix(COLOR.rgb, vec3(mix(dist_norm, abs(0.5-mod(TIME*bps*8.0, 1.0)), 0.33)), 1.0-(color_scale*2.0)); } + COLOR.rgb = mix(COLOR.rgb, vec3(1.0), 0.33); // brighten overall + COLOR.rgb = mix(COLOR.rgb, vec3(0.25), bright_scale); // Invert white outlines } else { COLOR.gb += 0.1; COLOR.rgb *= mix(abs(0.5-mod(TIME*bps, 1.0)), 1.0, 0.85); - COLOR.rgb *= scale; // Preserve black outlines + COLOR.rgb *= color_scale; // Preserve black outlines + COLOR.rgb = mix(COLOR.rgb, vec3(1.0), bright_scale); // Preserve white outlines } COLOR.a = texture(TEXTURE, UV).a; - if (sample.rgb == vec3(1.0)){ - COLOR.rgb = vec3(1.0); - } } \ No newline at end of file diff --git a/theme.gd b/theme.gd index 1e0b910..c40340b 100644 --- a/theme.gd +++ b/theme.gd @@ -32,3 +32,14 @@ var COLOR_ARRAY_DOUBLE_8 := PoolColorArray([ COLOR_DOUBLE, COLOR_DOUBLE, COLOR_DOUBLE, COLOR_DOUBLE, COLOR_DOUBLE, COLOR_DOUBLE, COLOR_DOUBLE, COLOR_DOUBLE ]) + +var screen_filter := Color(0.0, 0.0, 0.0, 0.2) + +var RADIAL_COL_ANGLES := PoolRealArray() # ideally const +var RADIAL_UNIT_VECTORS := PoolVector2Array() # ideally const + +func init_radial_values(): + for i in range(Rules.COLS): + var angle = deg2rad(fmod(Rules.FIRST_COLUMN_ANGLE_DEG + (i * Rules.COLS_ANGLE_DEG), 360.0)) + RADIAL_COL_ANGLES.push_back(angle) + RADIAL_UNIT_VECTORS.push_back(Vector2(cos(angle), sin(angle))) \ No newline at end of file