ROYGBV update order

This commit is contained in:
mehbark 2026-04-01 06:00:21 -04:00
parent 41cc6f7287
commit bd48850760
Signed by: mbk
GPG key ID: E333EC1335FFCCDB
10 changed files with 210 additions and 27 deletions

11
ball.gd Normal file
View file

@ -0,0 +1,11 @@
extends Piece
@export var rainbow: Gradient
func _ready() -> void:
super()
mesh.surface_set_material(0, mesh.surface_get_material(0).duplicate(true))
mesh.surface_get_material(0).albedo_color = rainbow.get_color(index)
func _process(delta: float) -> void:
super(delta)

1
ball.gd.uid Normal file
View file

@ -0,0 +1 @@
uid://caqjvn4spmm4p

View file

@ -26,7 +26,7 @@ func pieces() -> Array[Piece]:
# important for consistency. # important for consistency.
# everything involving pieces is done top to bottom, then left to right # everything involving pieces is done top to bottom, then left to right
# expensive? yes. wasteful? definitely. worth it? i think so. # expensive? yes. wasteful? definitely. worth it? i think so.
sorted.sort_custom(func(a, b): return a.lpos.y < b.lpos.y or (a.lpos.y == b.lpos.y and a.lpos.x < b.lpos.x)) sorted.sort_custom(func(a, b): return a.index < b.index)
return sorted return sorted
func pieces_at(pos: Vector2i) -> Array[Piece]: func pieces_at(pos: Vector2i) -> Array[Piece]:
@ -84,35 +84,23 @@ func finish_tween():
# uhh that's it lol? # uhh that's it lol?
# well, subphases: higher lvel magnitude moves first within a phase # well, subphases: higher lvel magnitude moves first within a phase
# TODO: this is wrong now (we have to simulate to know how long)
## returns the total time animation *will* take ## returns the total time animation *will* take
func step_anim_time() -> float: func step_anim_time() -> float:
var pieces_moving := pieces().filter(func(piece): return piece.lvel != Vector2i.ZERO).size() var pieces_moving := 5
return pieces_moving * anim_time return pieces_moving * anim_time
func do_step(): func do_step():
var pieces_moving := pieces().filter(func(piece): return piece.lvel != Vector2i.ZERO) # TODO: only balls move for now (of course)
var pieces_cardinal := pieces_moving.filter(func(piece): return piece.lvel.x == 0 or piece.lvel.y == 0)
var pieces_diagonal := pieces_moving.filter(func(piece): return piece.lvel.x != 0 and piece.lvel.y != 0)
var magnitude_sort := func(a: Piece, b: Piece):
return a.lvel.length() > b.lvel.length()
pieces_cardinal.sort_custom(magnitude_sort)
pieces_diagonal.sort_custom(magnitude_sort)
finish_tween() finish_tween()
var tween := get_tree().create_tween() var tween := get_tree().create_tween()
last_tween = tween last_tween = tween
for piece in pieces_cardinal: var balls := pieces().filter(func(p): return p.type == Piece.Type.Ball)
piece.do_step(self, tween)
for piece in pieces_diagonal:
piece.do_step(self, tween)
if pieces_moving.is_empty(): for ball in balls:
# no tweens -> invalid -> annoying error message ball.do_step(self, tween)
tween.kill()
func undo_step() -> Callable: func undo_step() -> Callable:
var undos: Array[Callable] = [] var undos: Array[Callable] = []

157
level/roygbv_00.tscn Normal file
View file

@ -0,0 +1,157 @@
[gd_scene load_steps=18 format=3 uid="uid://ql57xt12ybkq"]
[ext_resource type="Script" uid="uid://c8ywa33v3jq7t" path="res://board.gd" id="1_8kqtg"]
[ext_resource type="PackedScene" uid="uid://cnjmu3qesbndk" path="res://piece/player.tscn" id="2_kt6f8"]
[ext_resource type="PackedScene" uid="uid://bghr6ew34loyb" path="res://piece/ball.tscn" id="3_kt6f8"]
[ext_resource type="PackedScene" uid="uid://uf8vnylfqal1" path="res://piece/goal.tscn" id="4_56d6i"]
[ext_resource type="PackedScene" uid="uid://bkaa4sl1n2f5w" path="res://piece/wall.tscn" id="5_0asd3"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_56d6i"]
resource_local_to_scene = true
albedo_color = Color(0.92629945, 2.7193873e-06, 3.85046e-07, 1)
[sub_resource type="SphereMesh" id="SphereMesh_0asd3"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_56d6i")
radius = 0.3
height = 0.6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0asd3"]
resource_local_to_scene = true
albedo_color = Color(0.9244893, 0.4074873, 0.1344164, 1)
[sub_resource type="SphereMesh" id="SphereMesh_0ks07"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_0asd3")
radius = 0.3
height = 0.6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_1vqhm"]
resource_local_to_scene = true
albedo_color = Color(0.82362026, 0.7861889, 0.18114433, 1)
[sub_resource type="SphereMesh" id="SphereMesh_m21p2"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_1vqhm")
radius = 0.3
height = 0.6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_0ks07"]
resource_local_to_scene = true
albedo_color = Color(0.24896665, 0.77, 0.231, 1)
[sub_resource type="SphereMesh" id="SphereMesh_oref1"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_0ks07")
radius = 0.3
height = 0.6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_qv0xl"]
resource_local_to_scene = true
albedo_color = Color(0.15496138, 0.71618986, 0.8610338, 1)
[sub_resource type="SphereMesh" id="SphereMesh_xh78i"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_qv0xl")
radius = 0.3
height = 0.6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_m21p2"]
resource_local_to_scene = true
albedo_color = Color(0.8315036, 0.2150366, 0.7913129, 1)
[sub_resource type="SphereMesh" id="SphereMesh_1ogix"]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_m21p2")
radius = 0.3
height = 0.6
[node name="Level1" type="Node3D"]
script = ExtResource("1_8kqtg")
metadata/_custom_type_script = "uid://c8ywa33v3jq7t"
[node name="Player" parent="." instance=ExtResource("2_kt6f8")]
[node name="Goal" parent="." instance=ExtResource("4_56d6i")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 9.5, 0.057544, 2.5)
[node name="Ball" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 2.5, 0.3, 2.5)
mesh = SubResource("SphereMesh_0asd3")
lvel = Vector2i(1, 0)
[node name="Ball2" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 3.5, 0.3, 2.5)
mesh = SubResource("SphereMesh_0ks07")
index = 1
[node name="Ball3" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 4.5, 0.3, 2.5)
mesh = SubResource("SphereMesh_m21p2")
index = 2
[node name="Ball4" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 5.5, 0.3, 2.5)
mesh = SubResource("SphereMesh_oref1")
index = 3
[node name="Ball5" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 6.5, 0.3, 2.5)
mesh = SubResource("SphereMesh_xh78i")
index = 4
[node name="Ball6" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-4.371139e-08, 0, -1, 0, 1, 0, 1, 0, -4.371139e-08, 7.5, 0.3, 2.5)
mesh = SubResource("SphereMesh_1ogix")
index = 5
[node name="Ball7" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-4.371139e-08, 0, 1, 0, 1, 0, -1, 0, -4.371139e-08, 7.5, 0.59999967, 5.5)
mesh = SubResource("SphereMesh_0asd3")
skeleton = NodePath("../Ball6")
lvel = Vector2i(-1, 0)
[node name="Ball8" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-1, -8.742278e-08, 0, 8.742278e-08, -1, 0, 0, 0, 1, 6.5, 0.5999998, 5.5)
mesh = SubResource("SphereMesh_0ks07")
skeleton = NodePath("../Ball6")
index = 1
[node name="Ball9" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-1, -8.742278e-08, 0, 8.742278e-08, -1, 0, 0, 0, 1, 5.5, 0.59999985, 5.5)
mesh = SubResource("SphereMesh_m21p2")
skeleton = NodePath("../Ball6")
index = 2
[node name="Ball10" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-1, -8.742278e-08, 0, 8.742278e-08, -1, 0, 0, 0, 1, 4.5, 0.59999996, 5.5)
mesh = SubResource("SphereMesh_oref1")
skeleton = NodePath("../Ball6")
index = 3
[node name="Ball11" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(-1, -8.742278e-08, 0, 8.742278e-08, -1, 0, 0, 0, 1, 3.4999995, 0.6, 5.5)
mesh = SubResource("SphereMesh_xh78i")
skeleton = NodePath("../Ball6")
index = 4
[node name="Ball12" parent="." instance=ExtResource("3_kt6f8")]
transform = Transform3D(4.371139e-08, -8.742278e-08, 1, -3.821371e-15, -1, -8.742278e-08, 1, 0, -4.371139e-08, 2.4999995, 0.60000014, 5.5)
mesh = SubResource("SphereMesh_1ogix")
skeleton = NodePath("../Ball6")
index = 5
[node name="Goal2" parent="." instance=ExtResource("4_56d6i")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.057544, 5.5)
[node name="Wall" parent="." instance=ExtResource("5_0asd3")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0.600054, 5.5)
[node name="Wall2" parent="." instance=ExtResource("5_0asd3")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.5, 0.600054, 2.5)
[node name="Wall3" parent="." instance=ExtResource("5_0asd3")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 8.5, 0.600054, 5.5)
[node name="Wall4" parent="." instance=ExtResource("5_0asd3")]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 1.5, 0.600054, 2.5)

View file

@ -11,6 +11,12 @@ extends Node3D
@onready var victory_indicator: Sprite2D = $VictoryIndicator @onready var victory_indicator: Sprite2D = $VictoryIndicator
# TODO: tutorialize slowmo when things get complicated # TODO: tutorialize slowmo when things get complicated
# TODO: RAINBOW BALLS FOR ORDER!
# TODO: colorblind-accessible order
# TODO: make sure tutorial teaches undo/redo to new players
# TODO: ROYGBIV VIBGYOR example level
# TODO: I BEG YOU TO NEVER HAVE TWO BALLS OF THE SAME COLOR IN THE SAME LEVEl
# although i guess that being tricky means i should definitely do it
var hist := UndoRedo.new() var hist := UndoRedo.new()
var board: Board var board: Board
@ -21,6 +27,7 @@ var level_num := -1
@export var test := false @export var test := false
# TODO: yet more levels # TODO: yet more levels
var levels: Array[PackedScene] = [ var levels: Array[PackedScene] = [
preload("res://level/roygbv_00.tscn"),
preload("res://level/player_barrier_01.tscn"), preload("res://level/player_barrier_01.tscn"),
preload("res://level/level_00.tscn"), preload("res://level/level_00.tscn"),
preload("res://level/level_01.tscn"), preload("res://level/level_01.tscn"),

View file

@ -29,9 +29,9 @@ noise_type = 3
domain_warp_frequency = 0.28 domain_warp_frequency = 0.28
[sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7mycd"] [sub_resource type="NoiseTexture2D" id="NoiseTexture2D_7mycd"]
invert = true
color_ramp = SubResource("Gradient_lquwl")
noise = SubResource("FastNoiseLite_lquwl") noise = SubResource("FastNoiseLite_lquwl")
color_ramp = SubResource("Gradient_lquwl")
invert = true
[sub_resource type="ShaderMaterial" id="ShaderMaterial_lquwl"] [sub_resource type="ShaderMaterial" id="ShaderMaterial_lquwl"]
render_priority = 0 render_priority = 0

View file

@ -1,9 +1,11 @@
[gd_resource type="SphereMesh" load_steps=2 format=3 uid="uid://bxuewsvlsvexw"] [gd_resource type="SphereMesh" load_steps=2 format=3 uid="uid://bxuewsvlsvexw"]
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yae82"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_yae82"]
albedo_color = Color(0.997528, 0.415884, 0.114771, 1) resource_local_to_scene = true
albedo_color = Color(0.92629945, 2.7193873e-06, 3.85046e-07, 1)
[resource] [resource]
resource_local_to_scene = true
material = SubResource("StandardMaterial3D_yae82") material = SubResource("StandardMaterial3D_yae82")
radius = 0.3 radius = 0.3
height = 0.6 height = 0.6

View file

@ -42,12 +42,16 @@ func lpos_of_pos(pos: Vector3) -> Vector2i:
@export var type: Piece.Type @export var type: Piece.Type
## lower index -> updated earlier
@export_range(0, 6) var index: int = 0
var speedometer: Label3D var speedometer: Label3D
@onready var arrow := get_node_or_null("Arrow") as MeshInstance3D @onready var arrow := get_node_or_null("Arrow") as MeshInstance3D
func do_step(board: Board, tween: Tween): func do_step(board: Board, tween: Tween):
var move := lvel.clampi(-1, 1) var move := lvel.clampi(-1, 1)
var new_pos := lpos + move var new_pos := lpos + move
if new_pos == lpos: return
# ball being collided *with* gets the remainder of the momentum # ball being collided *with* gets the remainder of the momentum
# EMERGENT COMPLEXITY!??!? # EMERGENT COMPLEXITY!??!?
if board.solid_at(new_pos): if board.solid_at(new_pos):
@ -137,8 +141,11 @@ func format_vel(vel: Vector2) -> String:
return "%d,%d" % [abs(vel.x),abs(vel.y)] return "%d,%d" % [abs(vel.x),abs(vel.y)]
func _process(_delta: float) -> void: func _process(_delta: float) -> void:
update_speedometer()
func update_speedometer():
speedometer.text = format_vel(lvel_displayed) speedometer.text = format_vel(lvel_displayed)
if arrow: if arrow:
arrow.visible = lvel_displayed != Vector2i.ZERO arrow.visible = lvel_displayed != Vector2i.ZERO
if lvel != Vector2i.ZERO: if lvel_displayed != Vector2i.ZERO:
rotation.y = (1.0*lvel_displayed.clampi(-1,1)).angle_to(Vector2.UP) rotation.y = (1.0*lvel_displayed.clampi(-1,1)).angle_to(Vector2.UP)

View file

@ -1,9 +1,17 @@
[gd_scene load_steps=5 format=3 uid="uid://bghr6ew34loyb"] [gd_scene load_steps=6 format=3 uid="uid://bghr6ew34loyb"]
[ext_resource type="SphereMesh" uid="uid://bxuewsvlsvexw" path="res://model/ball.tres" id="1_qixli"] [ext_resource type="SphereMesh" uid="uid://bxuewsvlsvexw" path="res://model/ball.tres" id="1_qixli"]
[ext_resource type="Script" uid="uid://bq3a5hhccxndn" path="res://piece.gd" id="2_c3ygy"] [ext_resource type="Script" uid="uid://caqjvn4spmm4p" path="res://ball.gd" id="2_tqeq4"]
[ext_resource type="ArrayMesh" uid="uid://er57431oil1l" path="res://model/arrow.res" id="3_tqeq4"] [ext_resource type="ArrayMesh" uid="uid://er57431oil1l" path="res://model/arrow.res" id="3_tqeq4"]
[sub_resource type="Gradient" id="Gradient_tqeq4"]
interpolation_mode = 1
interpolation_color_space = 2
offsets = PackedFloat32Array(0.006329114, 0.16666667, 0.33333334, 0.5, 0.6666667, 0.8333333)
colors = PackedColorArray(0.92629945, 2.7193873e-06, 3.85046e-07, 1, 0.9244893, 0.4074873, 0.1344164, 1, 0.82362026, 0.7861889, 0.18114433, 1, 0.24896665, 0.77, 0.231, 1, 0.15496138, 0.71618986, 0.8610338, 1, 0.8315036, 0.2150366, 0.7913129, 1)
metadata/_snap_enabled = true
metadata/_snap_count = 6
[sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tqeq4"] [sub_resource type="StandardMaterial3D" id="StandardMaterial3D_tqeq4"]
transparency = 1 transparency = 1
albedo_color = Color(0.996078, 0.415686, 0.113725, 0.627451) albedo_color = Color(0.996078, 0.415686, 0.113725, 0.627451)
@ -11,11 +19,13 @@ albedo_color = Color(0.996078, 0.415686, 0.113725, 0.627451)
[node name="Ball" type="MeshInstance3D"] [node name="Ball" type="MeshInstance3D"]
transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.3, 0.5) transform = Transform3D(1, 0, 0, 0, 1, 0, 0, 0, 1, 0.5, 0.3, 0.5)
mesh = ExtResource("1_qixli") mesh = ExtResource("1_qixli")
script = ExtResource("2_c3ygy") script = ExtResource("2_tqeq4")
rainbow = SubResource("Gradient_tqeq4")
type = 2 type = 2
metadata/_custom_type_script = "uid://bq3a5hhccxndn" metadata/_custom_type_script = "uid://bq3a5hhccxndn"
[node name="Arrow" type="MeshInstance3D" parent="."] [node name="Arrow" type="MeshInstance3D" parent="."]
transform = Transform3D(-8.74228e-09, 0, 0.2, 0, 0.2, 0, -0.2, 0, -8.74228e-09, 0.00918186, 0.0516835, -0.568106) transform = Transform3D(-8.74228e-09, 0, 0.2, 0, 0.2, 0, -0.2, 0, -8.74228e-09, 0.00918186, 0.0516835, -0.568106)
visible = false
mesh = ExtResource("3_tqeq4") mesh = ExtResource("3_tqeq4")
surface_material_override/0 = SubResource("StandardMaterial3D_tqeq4") surface_material_override/0 = SubResource("StandardMaterial3D_tqeq4")

View file

@ -13,7 +13,7 @@ config_version=5
config/name="rolltime" config/name="rolltime"
config/description="it's rolltime" config/description="it's rolltime"
run/main_scene="uid://lrk2whqxl0w0" run/main_scene="uid://lrk2whqxl0w0"
config/features=PackedStringArray("4.4", "GL Compatibility") config/features=PackedStringArray("4.5", "GL Compatibility")
config/icon="res://icon.svg" config/icon="res://icon.svg"
[display] [display]