Polishing a turd

This commit is contained in:
Jahn 2025-08-02 00:09:16 -04:00
parent 10552b377b
commit c9b566498d
16 changed files with 121 additions and 79 deletions

View File

@ -4,13 +4,11 @@ It works by instantiating an `Area2D` node with a polygon collision shape, and c
also be mildly modified to draw level geometry dynamically. also be mildly modified to draw level geometry dynamically.
In either case, the challenge is taming an otherwise automatic system. In either case, the challenge is taming an otherwise automatic system.
Objects move on their own. You only control the pencil. Objects move on their own. You only control the ~~pencil~~ pen.
## Current questions # TODO:
* Should it be about capturing only the correct game entities? * swap pencil out for pen
* Should it be about drawing level geometry to guide game entities to a goal? * add grouping code
* multipliers for combos
## Current definites * penalties for not-combos
* Doodles-in-the-margins lined paper aesthetic * ignore all erroneous gestures, gesture recognition is probably my fault
* 2px outlines, simple colors
* Can likely use shaders to make it appear slightly sketchy and animated

Binary file not shown.

Before

Width:  |  Height:  |  Size: 1.1 KiB

After

Width:  |  Height:  |  Size: 1.1 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 97 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 92 KiB

After

Width:  |  Height:  |  Size: 97 KiB

View File

@ -1,3 +0,0 @@
[gd_scene format=3 uid="uid://cp2qdqu5ti42c"]
[node name="MouseFling" type="Node2D"]

View File

@ -1,35 +1,37 @@
extends Node2D extends Node2D
@onready var CURSOR = $Cursor @onready var CURSOR = $Cursor
var is_drawing : bool = false
func _ready() -> void: func _ready() -> void:
for x in range(64, get_viewport_rect().size.x, 96): for x in range(64, get_viewport_rect().size.x, 96):
for y in range(64, get_viewport_rect().size.y, 96): for y in range(64, get_viewport_rect().size.y, 96):
var c = Globals.SCENE_COLLECTABLE.instantiate() var c = Globals.SCENE_COLLECTABLE.instantiate()
c.global_position = Vector2(x, y) c.global_position = Vector2(x, y)
if randf() < .2: c.type = randi() % 2
c.is_bad = true
add_child(c) add_child(c)
$Camera2D.position = get_viewport_rect().size / 2 $Camera2D.position = get_viewport_rect().size / 2
func _draw() -> void: #func _draw() -> void:
var trail = CURSOR.get_tail(Globals.HISTORY_LENGTH) #var trail = CURSOR.get_tail(Globals.HISTORY_LENGTH)
#
if trail.size() <= 0: #if trail.size() <= 0:
return #return
#
for i in range(trail.size() - 1): #for i in range(trail.size() - 1):
var color #var color
if trail.size() > Globals.HISTORY_LENGTH * .66: #if trail.size() > Globals.HISTORY_LENGTH * .66:
color = Color(.5,0,0,1) #color = Color(.5,0,0,1)
elif trail.size() > Globals.HISTORY_LENGTH * .33: #elif trail.size() > Globals.HISTORY_LENGTH * .33:
color = Color(.5,.5,0,1) #color = Color(.5,.5,0,1)
else: #else:
color = Color(0,.5,0,1) #color = Color(0,.5,0,1)
draw_line(trail[i], trail[i + 1], color , Globals.LINE_THICC, false) #draw_line(trail[i], trail[i + 1], color , Globals.LINE_THICC, false)
func _process(delta: float) -> void: func _process(delta: float) -> void:
queue_redraw() if is_drawing:
var trail = CURSOR.get_tail(Globals.HISTORY_LENGTH)
$LineProgress/InkWell.points = PackedVector2Array(trail)
while CURSOR.loop_stack.size() > 0: while CURSOR.loop_stack.size() > 0:
var loop = CURSOR.loop_stack.pop_back() var loop = CURSOR.loop_stack.pop_back()
@ -37,21 +39,18 @@ func _process(delta: float) -> void:
func create_loop_object(loop:Array): func create_loop_object(loop:Array):
var scene = Globals.SCENE_LOOP.instantiate() var scene = Globals.SCENE_LOOP.instantiate()
var polygon_collider = scene.get_node("PolygonCollision") as CollisionPolygon2D scene.points = loop
polygon_collider.polygon = PackedVector2Array(loop) if Geometry2D.decompose_polygon_in_convex(PackedVector2Array(loop)).size() == 0:
scene.is_error = true
add_child(scene) add_child(scene)
await get_tree().create_timer(.2).timeout await get_tree().create_timer(.2).timeout
var contents = scene.get_contained_nodes() var contents = scene.get_contained_nodes()
get_tree().queue_delete(scene)
print(contents) print(contents)
var collectables = get_tree().get_nodes_in_group("collectable") var collectables = get_tree().get_nodes_in_group("collectable")
for i in contents: for i in contents:
if not (i in collectables): if not (i in collectables):
continue continue
if i.is_bad: # TODO: color matching logic
print("ouch")
i.remove()
else:
i.remove() i.remove()
func _on_cursor_started_drawing(pos:Vector2) -> void: func _on_cursor_started_drawing(pos:Vector2) -> void:
@ -61,6 +60,8 @@ func _on_cursor_started_drawing(pos:Vector2) -> void:
t.tween_property(Engine, "time_scale", 0.2, .2) t.tween_property(Engine, "time_scale", 0.2, .2)
$StartMarker.global_position = pos $StartMarker.global_position = pos
$StartMarker.visible = true $StartMarker.visible = true
$LineProgress.visible = true
is_drawing = true
func _on_cursor_stopped_drawing() -> void: func _on_cursor_stopped_drawing() -> void:
print("stopped drawing") print("stopped drawing")
@ -68,3 +69,5 @@ func _on_cursor_stopped_drawing() -> void:
var t = get_tree().create_tween() var t = get_tree().create_tween()
t.tween_property(Engine, "time_scale", 1.0, .2) t.tween_property(Engine, "time_scale", 1.0, .2)
$StartMarker.visible = false $StartMarker.visible = false
$LineProgress.visible = false
is_drawing = false

View File

@ -1,9 +1,10 @@
[gd_scene load_steps=9 format=3 uid="uid://d1bduqxqx10jb"] [gd_scene load_steps=10 format=3 uid="uid://d1bduqxqx10jb"]
[ext_resource type="Script" uid="uid://b1ddnopgn4scy" path="res://scenes/debug/MouseLoop.gd" id="1_x04i4"] [ext_resource type="Script" uid="uid://b1ddnopgn4scy" path="res://scenes/debug/MouseLoop.gd" id="1_x04i4"]
[ext_resource type="PackedScene" uid="uid://byipv4uqxdtfk" path="res://scenes/objects/Cursor.tscn" id="3_aaj44"] [ext_resource type="PackedScene" uid="uid://byipv4uqxdtfk" path="res://scenes/objects/Cursor.tscn" id="3_aaj44"]
[ext_resource type="Texture2D" uid="uid://c7en2ehk2mvk0" path="res://assets/textures/lined-paper.png" id="3_u4ca0"] [ext_resource type="Texture2D" uid="uid://c7en2ehk2mvk0" path="res://assets/textures/lined-paper.png" id="3_u4ca0"]
[ext_resource type="PackedScene" uid="uid://dnr505je252gd" path="res://scenes/objects/StartMarker.tscn" id="4_u4ca0"] [ext_resource type="PackedScene" uid="uid://dnr505je252gd" path="res://scenes/objects/StartMarker.tscn" id="4_u4ca0"]
[ext_resource type="PackedScene" uid="uid://dnkw8qq4rm0td" path="res://scenes/objects/InkWell.tscn" id="5_olkr6"]
[sub_resource type="RectangleShape2D" id="RectangleShape2D_va2mg"] [sub_resource type="RectangleShape2D" id="RectangleShape2D_va2mg"]
size = Vector2(100, 591) size = Vector2(100, 591)
@ -59,7 +60,12 @@ stretch_mode = 1
[node name="StartMarker" parent="." instance=ExtResource("4_u4ca0")] [node name="StartMarker" parent="." instance=ExtResource("4_u4ca0")]
visible = false visible = false
[node name="LineProgress" type="Node2D" parent="."]
visible = false
z_index = -1 z_index = -1
[node name="InkWell" parent="LineProgress" instance=ExtResource("5_olkr6")]
[connection signal="started_drawing" from="Cursor" to="." method="_on_cursor_started_drawing"] [connection signal="started_drawing" from="Cursor" to="." method="_on_cursor_started_drawing"]
[connection signal="stopped_drawing" from="Cursor" to="." method="_on_cursor_stopped_drawing"] [connection signal="stopped_drawing" from="Cursor" to="." method="_on_cursor_stopped_drawing"]

View File

@ -0,0 +1,19 @@
[gd_scene load_steps=3 format=3 uid="uid://dnkw8qq4rm0td"]
[sub_resource type="Curve" id="Curve_u4ca0"]
_data = [Vector2(0, 1), 0.0, 0.0, 0, 0, Vector2(0.904255, 0.505618), 0.0, 0.0, 0, 0, Vector2(1, 0), 0.0, 0.0, 0, 0]
point_count = 3
[sub_resource type="Gradient" id="Gradient_olkr6"]
offsets = PackedFloat32Array(0, 0.76, 1)
colors = PackedColorArray(0.466186, 0.00100478, 0.617304, 1, 0.621544, 0.219829, 0.753819, 1, 0.99221, 0, 0.512235, 1)
[node name="InkWell" type="Line2D"]
z_index = 1
width = 16.0
width_curve = SubResource("Curve_u4ca0")
default_color = Color(6.61798e-07, 0.260467, 2.40654e-08, 1)
gradient = SubResource("Gradient_olkr6")
joint_mode = 2
begin_cap_mode = 2
end_cap_mode = 2

View File

@ -1,10 +1,26 @@
[gd_scene load_steps=2 format=3 uid="uid://c3qo6pmowd5en"] [gd_scene load_steps=5 format=3 uid="uid://c3qo6pmowd5en"]
[ext_resource type="Script" uid="uid://bi2yo4l1m60iu" path="res://scenes/objects/loop.gd" id="1_vv7t2"] [ext_resource type="Script" uid="uid://bi2yo4l1m60iu" path="res://scenes/objects/loop.gd" id="1_vv7t2"]
[ext_resource type="PackedScene" uid="uid://dnkw8qq4rm0td" path="res://scenes/objects/InkWell.tscn" id="2_8ki1u"]
[sub_resource type="Gradient" id="Gradient_4e0vx"]
colors = PackedColorArray(0, 1, 0.65, 1, 0, 1, 0.65, 1)
[sub_resource type="Gradient" id="Gradient_8ki1u"]
interpolation_mode = 1
offsets = PackedFloat32Array(0)
colors = PackedColorArray(0.835056, 0, 0.286475, 1)
[node name="Loop" type="Area2D"] [node name="Loop" type="Area2D"]
script = ExtResource("1_vv7t2") script = ExtResource("1_vv7t2")
[node name="PolygonCollision" type="CollisionPolygon2D" parent="."] [node name="PolygonCollision" type="CollisionPolygon2D" parent="."]
[node name="InkWellGood" parent="." instance=ExtResource("2_8ki1u")]
gradient = SubResource("Gradient_4e0vx")
[node name="InkWellBad" parent="." instance=ExtResource("2_8ki1u")]
visible = false
gradient = SubResource("Gradient_8ki1u")
[connection signal="body_entered" from="." to="." method="_on_body_entered"] [connection signal="body_entered" from="." to="." method="_on_body_entered"]

View File

@ -1,18 +1,10 @@
[gd_scene load_steps=4 format=3 uid="uid://dnr505je252gd"] [gd_scene load_steps=2 format=3 uid="uid://dnr505je252gd"]
[ext_resource type="Shader" uid="uid://clj5gpccox0tb" path="res://scenes/objects/StartMarker.gdshader" id="1_kpqbh"]
[ext_resource type="Script" uid="uid://bwut7fxknsnos" path="res://scenes/objects/start_marker.gd" id="1_u6erm"] [ext_resource type="Script" uid="uid://bwut7fxknsnos" path="res://scenes/objects/start_marker.gd" id="1_u6erm"]
[sub_resource type="ShaderMaterial" id="ShaderMaterial_3ykre"]
shader = ExtResource("1_kpqbh")
shader_parameter/speed = 16.0
shader_parameter/scale = 8.0
shader_parameter/color_a = Color(0.158472, 0.158472, 0.158472, 1)
shader_parameter/color_b = Color(0.864675, 0.864675, 0.864675, 1)
[node name="StartMarker" type="Line2D"] [node name="StartMarker" type="Line2D"]
material = SubResource("ShaderMaterial_3ykre")
points = PackedVector2Array(-64, -64, 64, -64, 64, 64, -64, 64) points = PackedVector2Array(-64, -64, 64, -64, 64, 64, -64, 64)
closed = true closed = true
width = 32.0 width = 32.0
default_color = Color(0.466667, 0, 0.615686, 1)
script = ExtResource("1_u6erm") script = ExtResource("1_u6erm")

View File

@ -1,19 +1,21 @@
extends CharacterBody2D extends CharacterBody2D
@export var is_bad : bool = false @export_enum("color", "red", "blue", "green", "black") var type : int = 3
func _ready() -> void: func _ready() -> void:
velocity = Vector2.from_angle(randf() * PI * 2) * 50 velocity = Vector2.from_angle(randf() * PI * 2) * 25
if is_bad: match type:
modulate = Color.RED 0: modulate = Color.RED
1: modulate = Color.BLUE
2: modulate = Color.GREEN
func _process(delta: float) -> void: func _process(delta: float) -> void:
var results = move_and_collide(velocity * delta, false) var results = move_and_collide(velocity * delta, false)
if results != null: if results != null:
velocity = velocity.reflect(Vector2.from_angle(results.get_angle())) velocity = velocity.reflect(Vector2.from_angle(results.get_angle()))
func vibrate() -> void:
$Sprite2D.offset = Vector2((randf() - .5) * 2, (randf() - .5) * 2) * 1
func remove() -> void: func remove() -> void:
if is_bad:
velocity = Vector2(0,0)
await get_tree().create_tween().tween_property(self, "scale", Vector2(2,2), 1.0).finished
get_tree().queue_delete(self) get_tree().queue_delete(self)

View File

@ -15,17 +15,15 @@ func _ready() -> void:
global_position = get_viewport_rect().size / 2 global_position = get_viewport_rect().size / 2
func _process(delta: float) -> void: func _process(delta: float) -> void:
if global_position.y < 32: $IconNormal.rotation_degrees = ((get_viewport_rect().size / 2) - Vector2(-10000, -10000)).normalized().dot(Vector2.from_angle(45.))
$IconNormal.scale.y = -1.0
else:
$IconNormal.scale.y = 1.0
if global_position.x > get_viewport_rect().size.x - 32:
$IconNormal.scale.x = -1.0
else:
$IconNormal.scale.x = 1.0
func _input(event: InputEvent) -> void: func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion: if event is InputEventMouseButton:
Input.mouse_mode = Input.MOUSE_MODE_CAPTURED
if event is InputEventKey:
if event.keycode == KEY_ESCAPE:
Input.mouse_mode = Input.MOUSE_MODE_VISIBLE
if event is InputEventMouseMotion and Input.mouse_mode == Input.MOUSE_MODE_CAPTURED:
var direction = event.relative.normalized() var direction = event.relative.normalized()
# truthfully should calibrate by mouse # truthfully should calibrate by mouse
# need a max speed for fair gameplay # need a max speed for fair gameplay
@ -38,6 +36,7 @@ func _input(event: InputEvent) -> void:
emit_signal("started_drawing", global_position) emit_signal("started_drawing", global_position)
is_drawing = true is_drawing = true
push_history_stack(global_position) push_history_stack(global_position)
Globals.CURRENT_LINE = positions_history
else: else:
if is_close_to_loop(): if is_close_to_loop():
create_valid_loop() create_valid_loop()

View File

@ -1,22 +1,28 @@
extends Area2D extends Area2D
var contents : Array = [] var contained_nodes : Array = []
var points : Array = []
const LINE_THICC = 6.0 const LINE_THICC = 6.0
func _ready() -> void: var is_error : bool = false
await get_tree().create_timer(.2).timeout
$PolygonCollision.disabled = true
func _draw() -> void: func _ready() -> void:
draw_polyline( $PolygonCollision.polygon = points
$PolygonCollision.polygon, $InkWellGood.points = PackedVector2Array(points)
Color.BLACK, LINE_THICC, false) if is_error:
draw_line( $InkWellBad.points = $InkWellGood.points
$PolygonCollision.polygon[0], $PolygonCollision.polygon[$PolygonCollision.polygon.size() - 1], $InkWellGood.visible = false
Color.BLACK, LINE_THICC, false) $InkWellBad.visible = true
await get_tree().create_timer(0.2).timeout
self.remove()
func _on_body_entered(body: Node2D) -> void: func _on_body_entered(body: Node2D) -> void:
contents.append(body) contained_nodes.append(body)
func get_contained_nodes() -> Array: func get_contained_nodes() -> Array:
return contents return contained_nodes
func remove() -> void:
if is_error:
await get_tree().create_tween().tween_property($InkWellBad, "width", 0.0, 0.5).finished
get_tree().queue_delete(self)

View File

@ -6,3 +6,6 @@ func _ready() -> void:
var a = deg_to_rad(i * 10) var a = deg_to_rad(i * 10)
points.append(Vector2(cos(a), -sin(a)) * ((self.width / 2.0) - Globals.SNAP_DISTANCE)) points.append(Vector2(cos(a), -sin(a)) * ((self.width / 2.0) - Globals.SNAP_DISTANCE))
self.points = points self.points = points
func _process(delta:float) -> void:
scale = Vector2(1,1) * (1.0 - (float(Globals.CURRENT_LINE.size()) / float(Globals.HISTORY_LENGTH)))

View File

@ -7,3 +7,4 @@ const SCENE_START_MARKER = preload("res://scenes/objects/StartMarker.tscn")
const LINE_THICC = 4.0 const LINE_THICC = 4.0
const HISTORY_LENGTH = 196 const HISTORY_LENGTH = 196
const SNAP_DISTANCE = 32 const SNAP_DISTANCE = 32
var CURRENT_LINE = []