处理短按和长按、拖放和精灵重叠?
Handle short and long clicks, drag and drop and sprites overlapping?
我的游戏将使用触摸控制,但我在实现以下机制时遇到了很多麻烦。
当我短按精灵时,我想让它做一个简单的点击事件,在我的代码中,它应该高亮精灵。
但是当我长按一个 sprite 时,它应该在某一点锚定到光标并被它拖来拖去。当我释放它时,它应该停止跟随光标并留在原地。
最后但同样重要的是,我实际上正在处理多个精灵,我想始终影响最上面的精灵(z_index 明智)。
所以现在,我的代码如下所示:
# 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)
目前,唯一的问题是当我的光标下有另一个 sprite 时删除一个 sprite 会触发该 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"):
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)
像这样编码似乎可以使其正常工作。
基本上,我使用 is_holding 布尔值来收集有关精灵是否已被较早按下的信息。如果不是,is_action_just_released 应该完全忽略对 sprite 的任何操作。
欢迎提出更好的实施方法
我的游戏将使用触摸控制,但我在实现以下机制时遇到了很多麻烦。
当我短按精灵时,我想让它做一个简单的点击事件,在我的代码中,它应该高亮精灵。
但是当我长按一个 sprite 时,它应该在某一点锚定到光标并被它拖来拖去。当我释放它时,它应该停止跟随光标并留在原地。
最后但同样重要的是,我实际上正在处理多个精灵,我想始终影响最上面的精灵(z_index 明智)。
所以现在,我的代码如下所示:
# 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)
目前,唯一的问题是当我的光标下有另一个 sprite 时删除一个 sprite 会触发该 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"):
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)
像这样编码似乎可以使其正常工作。 基本上,我使用 is_holding 布尔值来收集有关精灵是否已被较早按下的信息。如果不是,is_action_just_released 应该完全忽略对 sprite 的任何操作。
欢迎提出更好的实施方法