0 votes

Hello, I am trying to recreate solitaire to get some practice in with the engine and also it being my first game I am making more or less.

I've started small and just wanted to be able to drag and drop some cards. I've got most of it down, however when two cards overlap I will drag both of them if the mouse is over the overlapping section.

I have tried to increase the Z-Axis, when the cards overlap then check the Z-Axis when moving. This kinda works, but it needs a little refinement. I just can't figure out this logic properly. This also doesn't allow me to select the non-overlapping part of a card that is on the lower Z-Axis.

I have an Area2D, with a child Sprite and CollisionShape2D.

Here is my script:

extends Area2D

const TEXTURE_WIDTH = 30
const TEXTURE_HEIGHT = 45

var pos_offset = Vector2()
var mouse_pressed = false

func _ready():
    set_process_input(true)

func _input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton:
        if event.button_index == BUTTON_LEFT and event.pressed:
            mouse_pressed = true
            pos_offset = self.position - get_global_mouse_position()

        if event.button_index == BUTTON_LEFT and not event.pressed:
            mouse_pressed = false

func _process(delta):
    if mouse_pressed and self.get_z() == 1:
        self.position = get_global_mouse_position() + pos_offset

        # Left
        if self.position.x < TEXTURE_WIDTH:
            self.position.x = TEXTURE_WIDTH
        # Right
        if self.position.x + TEXTURE_WIDTH > get_viewport().size.x:
            self.position.x = get_viewport().size.x - TEXTURE_WIDTH
        # Top
        if self.position.y < TEXTURE_HEIGHT:
            self.position.y = TEXTURE_HEIGHT
        # Bottom
        if self.position.y + TEXTURE_HEIGHT > get_viewport().size.y:
            self.position.y = get_viewport().size.y - TEXTURE_HEIGHT


func _on_Area2D_area_entered(area):
    if mouse_pressed and self.get_z() == 1:
        area.set_z(0)

func _on_Area2D_area_exited(area):
    if mouse_pressed:
        area.set_z(1)
in Engine by (20 points)

1 Answer

+2 votes

After having a think about it over-night, I've managed to come up with a slight solution. So I'm posting my answer to help others who have the same problem.

I needed to change the _on_Area2D_area_exited function.

It is currently this:

func _on_Area2D_area_exited(area):
    if self.get_z() == 0:
        mouse_pressed = false
        self.set_z(1)

Currently this allows me to move cards that overlap, even when clicking on the overlapping section. There is a drawback in that you will be unable to click on the bottom card without moving the top card first.

by (20 points)

How'd you go with your game? Did you finish it? Making a solitaire game myself right now and came across this whilst looking for Drag and Drop. Be keen to share what I'm up to as I go, I have only started though.

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.