My game is going to be using touch controls and I'm having a lot of trouble implementing the following mechanics.
When I make a short click on a sprite, I want it to do a simple click event, in my code, it should highlight the sprite.
But when I make a long click on a sprite, it should at one point anchor to the cursor and be dragged around by it. When I release it, it should then stop following the cursor and stay in place.
Last but not least, I'm actually working with multiple sprites and I want to always influence the top-most sprite (z_index wise).
So right now, my code looks like this:
# Node2D, parent of my sprite
func _process(delta):
# Checks for clicks and hold, calls function based on events
if not owning_hand or not owning_hand.my_hand:
is_holding = false
return
if Input.is_action_just_released("click"):
owning_hand.drop_card()
is_holding = false
if not input_in_sprite:
is_holding = false
return
if Input.is_action_just_pressed("click"):
is_holding = true
if Input.is_action_just_released("click"):
if hold_time < HOLD_TARGET:
owning_hand.clicked_cards.append(self)
is_holding = false
if is_holding:
hold_time += delta
else:
hold_time = 0
if hold_time >= HOLD_TARGET:
owning_hand.held_cards.append(self)
func _input(event):
# If the mouse is in the sprite, set input_in_sprite to true
if not owning_hand or not owning_hand.my_hand:
return
if event is InputEventMouse and sprite.get_rect().has_point(to_local(event.position)) and not played:
input_in_sprite = true
else:
input_in_sprite = false
# Position2D, represents the player's input and methods
func _process(delta): # Gets the top most card z_index wise
# Checks for any clicked cards
print(held_cards)
if dragged_card:
dragged_card.position = get_global_mouse_position()
if clicked_cards:
var top_card = clicked_cards[0]
for Card in clicked_cards:
if Card.z_index > top_card.z_index:
top_card = Card
clicked_cards.clear()
highlight_card(top_card)
if held_cards:
var top_card = held_cards[0]
for Card in held_cards:
if Card.z_index > top_card.z_index:
top_card = Card
held_cards.clear()
drag_card(top_card)
func drag_card(card):
# Drags the card around
dragged_card = card
func drop_card():
# Drops the card
dragged_card = null
func highlight_card(card):
# Highlights the card
card.move_rotate(card.position + transform.y * -HIGHLIGHT_HEIGHT, card.rotation, REORGANISE_TIME)
At the moment, the only issue is that dropping a sprite when there's another sprite under my cursor triggers the click event of the sprite isn't being dropped.
To be frank, the code is pretty much okay for what I'm doing. I'm asking here to see if anyone knows a better way to code those mechanics.
func _process(delta):
# Checks for clicks and hold, calls function based on events
if not owning_hand or not owning_hand.my_hand:
is_holding = false
return
if Input.is_action_just_released("click"):
if hold_time < HOLD_TARGET and input_in_sprite and is_holding:
owning_hand.clicked_cards.append(self)
if owning_hand.dragged_card:
owning_hand.drop_card()
is_holding = false
if Input.is_action_just_pressed("click") and input_in_sprite:
is_holding = true
if is_holding:
hold_time += delta
else:
hold_time = 0
if hold_time >= HOLD_TARGET:
owning_hand.held_cards.append(self)
Coding it like this seems to make it work correctly. Basically, I used the is_holding bool to gather knowledge on if the sprite has been pressed earlier. If not, the is_action_just_released should completely ignore any action on the sprite.
Feel free to suggest better ways to implement this