Can someone please help. I am working on my small card game and there is one problem that I’ve been trying to fix for the past hour or so.
When the user selects a card and a drags it to one of the slots the card does not create a new instance of it self and place it in the slot and then removes it self. Well it does but its weird, the way it works I don’t know why but the card needs to be offsetted from the slot position for the card to be placed.
Video link (sorry i couldn’t attach the video because i am a new user so i had to upload it to youtube):
I see you have a couple of print statements when mouse enters and mouse exits, what is the output?
In this case it might be an idea to print to a label on mouse entered to see if that signal is working the way you expect it to.
I am not sure using the underlying slots mouse entered signal is ideal. The mouse registers at one point (usually/probably the top left of your card). You want to be able to drop that card when any part of the card is over the slot.
The print statement you see is the Game.mouse_on_slot, this variable is in the GAME script which is auto loaded. There is two signals in the slot that sets to true or false, that is mouse_entered() and mouse_exited(). The slot is detecting correctly whether the mouse has entered or exited it just the card itself, I just can’t find it.
I was talking about the Slot functions _on_mouse_entered() and _on_mouse_exited().
They have print statements. What is the output from them?
And man, you must post actual code. It is beyond frustrating trying to queue up a video to find code and then have to type that code in because…its a video.
I usually don’t even try to help when code isn’t posted and I probably am not alone in that.
On the text box you type into is a toolbar with something that looks like this </>
Use that tool to surround the code so that it retains its formatting.
I suspect that the Game.mouse_on_slot (or whatever it is called) is being reset on you.
Another way to test that is to add a setter to that variable that shows its state in a label.
var mouse_on_slot:bool = false:
set(value):
mouse_on_slot = value
my_debug_label.text = str(value)
The print statements on the Slot are print(“entered”) for the mouse_entered() and print(“exited”) on the mouse_exited() and like I said the detection on the Slot is correct.
#Slot
extends Control
func _on_mouse_entered():
print("entered")
Game.mouse_on_slot = true
Game.slot_name = name
func _on_mouse_exited():
print("exit")
Game.mouse_on_slot = false
Game.slot_name = null
#Card
extends Control
var is_selected : bool = false
var following_mouse : bool = false
var is_placed : bool = false
var tween_hover : Tween
var initial_pos : Vector2 = Vector2.ZERO
func _ready():
pass
func _process(_delta):
print(Game.mouse_on_slot)
if following_mouse:
global_position = get_global_mouse_position()
func _gui_input(event):
if event is InputEventMouseButton and event.button_index == 1:
if event.button_mask == 1:
if is_selected:
initial_pos = position
following_mouse = true
Game.card_scene = load("res://Cards/base_card.tscn")
Game.card_name = name
if event.button_mask == 0:
if Game.mouse_on_slot:
var temp_card = Game.card_scene.instantiate()
get_tree().get_root().get_child(1).get_child(0).find_child(Game.slot_name).add_child(temp_card)
get_tree().get_root().get_child(1).get_child(1).get_child(0).find_child(Game.card_name).queue_free()
is_selected = false
following_mouse = false
else:
following_mouse = false
is_selected = false
position = initial_pos
Game.card_scene = null
Game.card_name = null
func _on_mouse_entered():
is_selected = true
if tween_hover and tween_hover.is_running():
tween_hover.kill()
tween_hover = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
tween_hover.tween_property(self, "scale", Vector2(1.05, 1.05), 0.5)
func _on_mouse_exited():
if not following_mouse:
is_selected = false
if tween_hover and tween_hover.is_running():
tween_hover.kill()
tween_hover = create_tween().set_ease(Tween.EASE_OUT).set_trans(Tween.TRANS_ELASTIC)
tween_hover.tween_property(self, "scale", Vector2.ONE, 0.55)
if event.button_mask == 0:
if Game.mouse_on_slot:
var temp_card = Game.card_scene.instantiate()
get_tree().get_root().get_child(1).get_child(0).find_child(Game.slot_name).add_child(temp_card)
get_tree().get_root().get_child(1).get_child(1).get_child(0).find_child(Game.card_name).queue_free()
is_selected = false
following_mouse = false
else:
following_mouse = false
is_selected = false
Are you certain this line is getting the node you want?: get_tree().get_root().get_child(1).get_child(0).find_child(Game.slot_name).add_child(temp_card)
I would dump that into a variable and check that you are getting the slot you ask for.
If you are searching for a child node by name then you don’t need the extended get_child as find_child() has a parameter called recursive that defaults to true and will search the childs child (if I read the docs right…you can test that out).
var slot_node = get_tree().get_root().find_child(Game.slot_name)
slot_node.add_child(temp_card)
Similarly for the next line; check to make sure you are getting the node you want.
It seems strange to me that you are queue freeing the node Game.card_name but with get_childs() I have no way of seeing what exactly is being freed.
Maybe if you could describe the logic starting from if event.button_mask == 0
(Alternatively, you can post the project on github so we can have a look)
I still strongly suspect that mouse_exit() is being fired unexpectedly and causing your issues. I remember working with these mouse events and being surprised by the events firing when I thought they could not be.
I can’t see anything immediately obvious in the code that would reject the card drop.
To debug this, you are going to have to somehow trap the code flow at the point that you drop the card and it doesn’t take.
As an aside you have these statements identical on opposing sides of an if statement. One of them will run and since they are the same they need not be inside the if statement.
It also doesn’t make sense to me to load this scene inside the input event. Game.card_scene = load("res://Cards/base_card.tscn")
Load it once in the _ready() function and then instantiate it at will.
iirc GODOT handles repeated loading of the same resource elegantly so it won’t cause an issue but it seems disorganized to me.
(These last to things are not related to your issue)