mirror of
https://github.com/Steffo99/swear-jar.git
synced 2024-11-21 23:34:18 +00:00
Refactor Ghost
's placement feature into a separate PrecisePlacement
node
This commit is contained in:
parent
0baf2d74f0
commit
35095a84dd
4 changed files with 111 additions and 100 deletions
|
@ -41,111 +41,12 @@ var can_place: bool:
|
|||
preview_sprite.modulate = Color(1.0, 0.0, 0.0, 0.5)
|
||||
|
||||
|
||||
## Whether the ghost is currently being dragged or not.
|
||||
var is_being_dragged: bool
|
||||
|
||||
|
||||
func _ready():
|
||||
collision_mask = collision_mask_prevent_placement | collision_mask_delete_placement
|
||||
preview_sprite.texture = preview_texture
|
||||
|
||||
|
||||
## The degrees to rotate by when rotation is quantized.
|
||||
@export_range(1, 180, 1) var rotation_quantized_degrees: float = 45
|
||||
|
||||
## The degrees to rotate by when rotation is quantized and precise rotation is being requested.
|
||||
@export_range(1, 180, 1) var rotation_quantized_precise_degrees: float = 5
|
||||
|
||||
|
||||
## Get the degrees a piece should be rotated by when rotation is quantized.
|
||||
func get_rotation_quantized_degrees() -> float:
|
||||
var degrees = rotation_quantized_precise_degrees if Input.is_action_pressed("ghost_precise") else rotation_quantized_degrees
|
||||
var intensity = 1.0 if Input.is_action_just_pressed("ghost_clockwise") else 0.0 - 1.0 if Input.is_action_just_pressed("ghost_counterclockwise") else 0.0
|
||||
return degrees * intensity
|
||||
|
||||
## The last [InputEventMouse] received.
|
||||
var last_mouse_event: InputEventMouse = null
|
||||
|
||||
## The last [InputEventScreenTouch] or [InputEventScreenDrag] received for each possible touch index.
|
||||
var last_touch_events: Array[InputEvent] = [
|
||||
null, null, null, null, null,
|
||||
null, null, null, null, null,
|
||||
]
|
||||
|
||||
func count_active_touch_events() -> int:
|
||||
var total = 0
|
||||
for event in last_touch_events:
|
||||
if event != null:
|
||||
total += 1
|
||||
return total
|
||||
|
||||
func _input(event: InputEvent):
|
||||
# Count active events
|
||||
var count = count_active_touch_events()
|
||||
#print("[Ghost] Counting ", count, " active events!")
|
||||
|
||||
# Mouse drag
|
||||
if count == 0:
|
||||
# Mouse drag
|
||||
if event is InputEventMouseMotion and last_mouse_event:
|
||||
position += event.relative
|
||||
# Touch drag
|
||||
elif count == 1:
|
||||
# Touch drag
|
||||
if event is InputEventScreenDrag:
|
||||
position += event.relative
|
||||
# Handle rotation
|
||||
elif count == 2:
|
||||
# Find the previous event
|
||||
var previous
|
||||
if event is InputEventScreenTouch or event is InputEventScreenDrag:
|
||||
previous = last_touch_events[event.index]
|
||||
# At this point previous shouldn't be null
|
||||
# If it is, just try again at the next frame
|
||||
if previous == null:
|
||||
#print("[Ghost] Rotation occurred, but previous was null, so it was cancelled.")
|
||||
return
|
||||
# Find the other event
|
||||
var other
|
||||
for last_touch_index in len(last_touch_events):
|
||||
if event is InputEventScreenTouch or event is InputEventScreenDrag:
|
||||
if event.index == last_touch_index:
|
||||
continue
|
||||
if last_touch_events[last_touch_index] != null:
|
||||
other = last_touch_events[last_touch_index]
|
||||
# At this point other shouldn't be null
|
||||
# If it is, just try again at the next frame
|
||||
if other == null:
|
||||
#print("[Ghost] Rotation occurred, but other was null, so it was cancelled.")
|
||||
return
|
||||
# Find the two vectors between the touches, one using the previous position, and one using the current one
|
||||
var previous_vec: Vector2 = previous.position - other.position
|
||||
var current_vec: Vector2 = event.position - other.position
|
||||
#print("[Ghost] previous_vec: ", previous_vec, " | current_vec: ", current_vec)
|
||||
# Find the angle between the two vectors
|
||||
var rotation_radians = previous_vec.angle_to(current_vec)
|
||||
#print("[Ghost] Rotation was successful, rotating by: ", rotation_radians)
|
||||
# Apply the rotation
|
||||
rotation += rotation_radians
|
||||
|
||||
# Store last events
|
||||
if event is InputEventMouseButton:
|
||||
last_mouse_event = event if event.pressed else null
|
||||
#print("[Ghost] last_mouse_event updated in response to a InputEventMouseButton: ", last_mouse_event)
|
||||
elif event is InputEventMouseMotion and last_mouse_event != null:
|
||||
last_mouse_event = event
|
||||
#print("[Ghost] last_mouse_event updated in response to a InputEventMouseMotion: ", last_mouse_event)
|
||||
elif event is InputEventScreenTouch:
|
||||
last_touch_events[event.index] = event if event.pressed else null
|
||||
#print("[Ghost] last_touch_events[", event.index , "] updated in response to a InputEventScreenTouch: ", last_mouse_event)
|
||||
elif event is InputEventScreenDrag:
|
||||
last_touch_events[event.index] = event
|
||||
#print("[Ghost] last_touch_events[", event.index , "] updated in response to a InputEventScreenDrag: ", last_mouse_event)
|
||||
|
||||
|
||||
func _physics_process(_delta: float):
|
||||
# Handle quantized rotation
|
||||
rotation_degrees += get_rotation_quantized_degrees()
|
||||
# Update collision
|
||||
update_can_place()
|
||||
|
||||
|
|
|
@ -1,7 +1,8 @@
|
|||
[gd_scene load_steps=3 format=3 uid="uid://qtk4tm6l367w"]
|
||||
[gd_scene load_steps=4 format=3 uid="uid://qtk4tm6l367w"]
|
||||
|
||||
[ext_resource type="Script" path="res://interface/ghost/ghost.gd" id="1_1bq64"]
|
||||
[ext_resource type="PackedScene" uid="uid://c3p0jdf7416ac" path="res://converters/full_converter_shape.tscn" id="2_bo8dp"]
|
||||
[ext_resource type="PackedScene" uid="uid://cgpjm06hleokk" path="res://interface/ghost/precise_placement.tscn" id="3_70ahv"]
|
||||
|
||||
[node name="Ghost" type="Area2D"]
|
||||
collision_layer = 0
|
||||
|
@ -17,3 +18,5 @@ scale = Vector2(2.5, 2.5)
|
|||
[node name="PreviewSprite" type="Sprite2D" parent="PlacementShape"]
|
||||
modulate = Color(1, 1, 1, 0.5)
|
||||
z_index = 10
|
||||
|
||||
[node name="PrecisePlacement" parent="." instance=ExtResource("3_70ahv")]
|
||||
|
|
101
interface/ghost/precise_placement.gd
Normal file
101
interface/ghost/precise_placement.gd
Normal file
|
@ -0,0 +1,101 @@
|
|||
extends Node
|
||||
class_name PrecisePlacement
|
||||
|
||||
|
||||
## The degrees to rotate by when rotation is quantized.
|
||||
@export_range(1, 180, 1) var rotation_quantized_degrees: float = 45
|
||||
|
||||
## The degrees to rotate by when rotation is quantized and precise rotation is being requested.
|
||||
@export_range(1, 180, 1) var rotation_quantized_precise_degrees: float = 5
|
||||
|
||||
|
||||
## The [Node2D] this script should act on.
|
||||
@onready var target: Node2D = get_parent()
|
||||
|
||||
|
||||
## Whether the target is currently being dragged or not.
|
||||
var is_dragging: bool = false
|
||||
|
||||
## The last [InputEventMouse] received.
|
||||
var last_mouse_event: InputEventMouse = null
|
||||
|
||||
## The last [InputEventScreenTouch] or [InputEventScreenDrag] received for each possible touch index.
|
||||
var last_touch_events: Array[InputEvent] = [
|
||||
null, null, null, null, null,
|
||||
null, null, null, null, null,
|
||||
]
|
||||
|
||||
|
||||
## Count the number of non-[null] [last_touch_events].
|
||||
func count_active_touch_events() -> int:
|
||||
var total = 0
|
||||
for event in last_touch_events:
|
||||
if event != null:
|
||||
total += 1
|
||||
return total
|
||||
|
||||
## Handle event-based input
|
||||
func _input(event: InputEvent):
|
||||
# Count active events
|
||||
var count = count_active_touch_events()
|
||||
|
||||
# Mouse drag
|
||||
if count == 0:
|
||||
# Mouse drag
|
||||
if event is InputEventMouseMotion and last_mouse_event:
|
||||
target.position += event.relative
|
||||
# Touch drag
|
||||
elif count == 1:
|
||||
# Touch drag
|
||||
if event is InputEventScreenDrag:
|
||||
target.position += event.relative
|
||||
# Handle rotation
|
||||
elif count == 2:
|
||||
# Find the previous event
|
||||
var previous
|
||||
if event is InputEventScreenTouch or event is InputEventScreenDrag:
|
||||
previous = last_touch_events[event.index]
|
||||
# At this point previous shouldn't be null
|
||||
# If it is, just try again at the next frame
|
||||
if previous == null:
|
||||
return
|
||||
# Find the other event
|
||||
var other
|
||||
for last_touch_index in len(last_touch_events):
|
||||
if event is InputEventScreenTouch or event is InputEventScreenDrag:
|
||||
if event.index == last_touch_index:
|
||||
continue
|
||||
if last_touch_events[last_touch_index] != null:
|
||||
other = last_touch_events[last_touch_index]
|
||||
# At this point other shouldn't be null
|
||||
# If it is, just try again at the next frame
|
||||
if other == null:
|
||||
return
|
||||
# Find the two vectors between the touches, one using the previous position, and one using the current one
|
||||
var previous_vec: Vector2 = previous.position - other.position
|
||||
var current_vec: Vector2 = event.position - other.position
|
||||
# Find the angle between the two vectors
|
||||
var rotation_radians = previous_vec.angle_to(current_vec)
|
||||
# Apply the rotation
|
||||
target.rotation += rotation_radians
|
||||
|
||||
# Store last events
|
||||
if event is InputEventMouseButton:
|
||||
last_mouse_event = event if event.pressed else null
|
||||
elif event is InputEventMouseMotion and last_mouse_event != null:
|
||||
last_mouse_event = event
|
||||
elif event is InputEventScreenTouch:
|
||||
last_touch_events[event.index] = event if event.pressed else null
|
||||
elif event is InputEventScreenDrag:
|
||||
last_touch_events[event.index] = event
|
||||
|
||||
## Get the degrees that the target should be rotated by in a given frame when rotation is quantized.
|
||||
func get_rotation_quantized_degrees() -> float:
|
||||
var degrees = rotation_quantized_precise_degrees if Input.is_action_pressed("ghost_precise") else rotation_quantized_degrees
|
||||
var intensity = 1.0 if Input.is_action_just_pressed("ghost_clockwise") else 0.0 - 1.0 if Input.is_action_just_pressed("ghost_counterclockwise") else 0.0
|
||||
return degrees * intensity
|
||||
|
||||
## Handle polling-based input
|
||||
func _physics_process(_delta):
|
||||
# Handle quantized rotation
|
||||
target.rotation_degrees += get_rotation_quantized_degrees()
|
6
interface/ghost/precise_placement.tscn
Normal file
6
interface/ghost/precise_placement.tscn
Normal file
|
@ -0,0 +1,6 @@
|
|||
[gd_scene load_steps=2 format=3 uid="uid://cgpjm06hleokk"]
|
||||
|
||||
[ext_resource type="Script" path="res://interface/ghost/precise_placement.gd" id="1_e7b5h"]
|
||||
|
||||
[node name="PrecisePlacement" type="Node"]
|
||||
script = ExtResource("1_e7b5h")
|
Loading…
Reference in a new issue