|
|
|
|
Reply From: |
jgodfrey |
To me, the problem boils down to understanding the difference between:
- A “click”, intended to rotate the piece
- A “press, drag, release” intended to move the piece, but not rotate it.
Since the drag operation will, ultimately, trigger both a press and release of the button (just like a click), you need to somehow differentiate the two operations.
It seems you could do that in at least a few obvious ways.
- Calculate the time between the press and release of the button. With a “fast” time being interpreted as a click (so, rotate) and a slow time being interpreted as a drag (so, move the piece).
- The distance the mouse is moved between press and release events. With a “short” distance being interpreted as a click (so, rotate) and a “long” distance being interpreted as a drag.
- Some combination of both time and distance…
I’d guess that 2nd thing probably feels better in actual use, but you could try them all.
In all cases, you’d simply need to wire both the press and release event of the mouse. In the press event, you’d record either current time or the current position (depending on the method you choose).
Then, in the release event, you’d compare that recorded value to its current value (time or location).
Finally, you’d just need to calculate a delta between the two values and decide which side of the threshold it lies on (click or drag).
This is perfect, thanks a ton! I ended up going for a time-based solution using a Timer node, since I figured that, in a distance-based one, if a player held the button for a long time without moving and then released it, it would rotate the piece, which isn’t what I’m going for and would therefore also require a timer.
This is what I ended up with:
var dragging := false
onready var click_timer := $ClickTimer
func _process(_delta: float) -> void:
if dragging:
global_position = get_global_mouse_position()
func _on_ColoredTriangle_input_event(_viewport, event: InputEvent, _shape_idx) -> void:
if Input.is_action_just_pressed("click"):
click_timer.start(0.15)
if event.is_action_pressed("click"):
dragging = true
if event.is_action_released("click"):
dragging = false
if click_timer.get_time_left() > 0.0:
rotation_degrees += 90.0
maforn | 2020-08-21 20:42
Glad you got it working. One observation…
It looks like it’d be possible to quickly drag the piece some distance, release the mouse, and have it processed as a click (so, rotate). That would cause the piece to be both moved and rotated. Maybe it’s not really a problem in practice due to the relatively short 0.15
click timer.
However, you could mitigate it by recording the pieces position when the button is first pressed. Then, if you end up deciding the action was indeed a click (so, a rotate), just position the piece at the recorded (original) location. That way, if it was a click, it’d snap back to its original position if it did get dragged a little in the process.
jgodfrey | 2020-08-21 20:58
You’re right; I tested and it does happen, even if only when I’m deliberately trying to make it happen. Your suggestion also fixes it just right. However, in the long run, I think it won’t matter much; I’m planning on making it so that a piece’s position always resets to it’s original one unless it’s dragged to the correct slot.
maforn | 2020-08-21 22:43