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.
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
* Should it be about capturing only the correct game entities?
* Should it be about drawing level geometry to guide game entities to a goal?
## Current definites
* Doodles-in-the-margins lined paper aesthetic
* 2px outlines, simple colors
* Can likely use shaders to make it appear slightly sketchy and animated
# TODO:
* swap pencil out for pen
* add grouping code
* multipliers for combos
* penalties for not-combos
* ignore all erroneous gestures, gesture recognition is probably my fault

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

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"]
[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"]
material = SubResource("ShaderMaterial_3ykre")
points = PackedVector2Array(-64, -64, 64, -64, 64, 64, -64, 64)
closed = true
width = 32.0
default_color = Color(0.466667, 0, 0.615686, 1)
script = ExtResource("1_u6erm")

View File

@ -1,19 +1,21 @@
extends CharacterBody2D
@export var is_bad : bool = false
@export_enum("color", "red", "blue", "green", "black") var type : int = 3
func _ready() -> void:
velocity = Vector2.from_angle(randf() * PI * 2) * 50
if is_bad:
modulate = Color.RED
velocity = Vector2.from_angle(randf() * PI * 2) * 25
match type:
0: modulate = Color.RED
1: modulate = Color.BLUE
2: modulate = Color.GREEN
func _process(delta: float) -> void:
var results = move_and_collide(velocity * delta, false)
if results != null:
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:
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)

View File

@ -15,17 +15,15 @@ func _ready() -> void:
global_position = get_viewport_rect().size / 2
func _process(delta: float) -> void:
if global_position.y < 32:
$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
$IconNormal.rotation_degrees = ((get_viewport_rect().size / 2) - Vector2(-10000, -10000)).normalized().dot(Vector2.from_angle(45.))
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()
# truthfully should calibrate by mouse
# need a max speed for fair gameplay
@ -38,6 +36,7 @@ func _input(event: InputEvent) -> void:
emit_signal("started_drawing", global_position)
is_drawing = true
push_history_stack(global_position)
Globals.CURRENT_LINE = positions_history
else:
if is_close_to_loop():
create_valid_loop()

View File

@ -1,22 +1,28 @@
extends Area2D
var contents : Array = []
var contained_nodes : Array = []
var points : Array = []
const LINE_THICC = 6.0
func _ready() -> void:
await get_tree().create_timer(.2).timeout
$PolygonCollision.disabled = true
var is_error : bool = false
func _draw() -> void:
draw_polyline(
$PolygonCollision.polygon,
Color.BLACK, LINE_THICC, false)
draw_line(
$PolygonCollision.polygon[0], $PolygonCollision.polygon[$PolygonCollision.polygon.size() - 1],
Color.BLACK, LINE_THICC, false)
func _ready() -> void:
$PolygonCollision.polygon = points
$InkWellGood.points = PackedVector2Array(points)
if is_error:
$InkWellBad.points = $InkWellGood.points
$InkWellGood.visible = false
$InkWellBad.visible = true
await get_tree().create_timer(0.2).timeout
self.remove()
func _on_body_entered(body: Node2D) -> void:
contents.append(body)
contained_nodes.append(body)
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)
points.append(Vector2(cos(a), -sin(a)) * ((self.width / 2.0) - Globals.SNAP_DISTANCE))
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 HISTORY_LENGTH = 196
const SNAP_DISTANCE = 32
var CURRENT_LINE = []