Dartboard prototype with working raycast
This commit is contained in:
@@ -0,0 +1,97 @@
|
||||
extends Control
|
||||
# TrapezoidSwatch.gd (manual-drag version)
|
||||
# The trapezoid node ITSELF follows the cursor while dragging (no ghost).
|
||||
# On release over the board, it tells DropCatcher to paint the hit segment,
|
||||
# then asks the tray to consume the round's modifiers.
|
||||
|
||||
@export var paint_texture: Texture2D:
|
||||
set(value):
|
||||
paint_texture = value
|
||||
queue_redraw()
|
||||
@export_range(0.0, 1.0) var top_width_ratio := 0.55
|
||||
|
||||
# Set by the tray when it spawns this piece.
|
||||
var drop_catcher: Control # the DropCatcher node (does the 3D raycast+paint)
|
||||
var tray: Node # the ModifierTray (so we can consume on use)
|
||||
|
||||
# The full modifier this piece carries (texture + title + scoring rule).
|
||||
var modifier: Resource
|
||||
|
||||
var _dragging := false
|
||||
var _home_position := Vector2.ZERO # where it sits in the tray
|
||||
var _drag_offset := Vector2.ZERO # cursor-to-corner offset so it doesn't snap
|
||||
|
||||
func _ready() -> void:
|
||||
mouse_filter = Control.MOUSE_FILTER_STOP
|
||||
if custom_minimum_size == Vector2.ZERO:
|
||||
custom_minimum_size = Vector2(90, 110)
|
||||
size = custom_minimum_size
|
||||
|
||||
func _draw() -> void:
|
||||
var w := size.x
|
||||
var h := size.y
|
||||
var inset := w * (1.0 - top_width_ratio) * 0.5
|
||||
var points := PackedVector2Array([
|
||||
Vector2(inset, 0), Vector2(w - inset, 0),
|
||||
Vector2(w, h), Vector2(0, h),
|
||||
])
|
||||
if paint_texture != null:
|
||||
var uvs := PackedVector2Array([
|
||||
Vector2(inset / w, 0), Vector2((w - inset) / w, 0),
|
||||
Vector2(1, 1), Vector2(0, 1),
|
||||
])
|
||||
draw_polygon(points, PackedColorArray([Color.WHITE, Color.WHITE, Color.WHITE, Color.WHITE]), uvs, paint_texture)
|
||||
else:
|
||||
draw_colored_polygon(points, Color(0.8, 0.8, 0.8))
|
||||
var outline := points
|
||||
outline.append(points[0])
|
||||
draw_polyline(outline, Color(0, 0, 0, 0.6), 2.0)
|
||||
|
||||
func _gui_input(event: InputEvent) -> void:
|
||||
if event is InputEventMouseButton and event.button_index == MOUSE_BUTTON_LEFT:
|
||||
if event.pressed:
|
||||
_start_drag()
|
||||
else:
|
||||
_end_drag()
|
||||
|
||||
func _start_drag() -> void:
|
||||
_dragging = true
|
||||
_home_position = global_position
|
||||
_drag_offset = global_position - get_global_mouse_position()
|
||||
# top_level lets us move by global_position freely, ignoring the container
|
||||
# layout, WITHOUT reparenting (reparenting mid-drag breaks the release event).
|
||||
top_level = true
|
||||
z_index = 100 # float above everything during drag
|
||||
modulate.a = 0.85
|
||||
|
||||
func _end_drag() -> void:
|
||||
if not _dragging:
|
||||
return
|
||||
_dragging = false
|
||||
modulate.a = 1.0
|
||||
z_index = 0
|
||||
|
||||
# Ask the DropCatcher to try painting wherever we released.
|
||||
var painted := false
|
||||
print("PIECE released. drop_catcher=", drop_catcher, " modifier=", modifier)
|
||||
if drop_catcher == null:
|
||||
push_error("Piece has no drop_catcher reference! (tray export not set?)")
|
||||
elif not drop_catcher.has_method("apply_modifier_at_screen_pos"):
|
||||
push_error("drop_catcher has no apply_modifier_at_screen_pos method.")
|
||||
else:
|
||||
painted = drop_catcher.apply_modifier_at_screen_pos(get_global_mouse_position(), modifier)
|
||||
|
||||
if painted:
|
||||
# Used successfully: consume this round's modifier choices.
|
||||
if tray and tray.has_method("consume"):
|
||||
tray.consume()
|
||||
else:
|
||||
queue_free()
|
||||
else:
|
||||
# Missed the board: snap back home.
|
||||
top_level = false
|
||||
global_position = _home_position
|
||||
|
||||
func _process(_delta: float) -> void:
|
||||
if _dragging:
|
||||
global_position = get_global_mouse_position() + _drag_offset
|
||||
Reference in New Issue
Block a user