+2 votes

Hi all, I've done a few Godot tutorials and am now trying to do my first simple independent project, so sorry for the noob question.

I'm creating a very basic game of checkers. I've created the game board and a single token (KinematicBody2d with Sprite and CollisionShape2D children), and I've put an Area2D with a CollisionShape2D child over one single square (which will later be used on all squares).

I've figured out the code to move the checker around using my mouse. My question is how can I make it so that when I let go of the mouse on top of the square (i.e. anywhere within the Area2D Square), how can I get the checker to snap into place precisely at the same position as the square?

Here is my code so far for the mouse drag and drop:

extends KinematicBody2D

# Pickable needs to be selected from the inspector

var can_grab = false
var grabbed_offset = Vector2()

func _input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton:
        can_grab = event.pressed
        grabbed_offset = position - get_global_mouse_position()

func _process(delta):
    if Input.is_mouse_button_pressed(BUTTON_LEFT) and can_grab:
        position = get_global_mouse_position() + grabbed_offset

And here's my (undoubtedly bad) try at connecting the two nodes and getting them into the same position on release of the mouse, which doesn't work:

func _on_Square_body_entered(body):
    if not Input.is_mouse_button_pressed(BUTTON_LEFT) and can_grab:
        body.global_position = $Square.global_position
in Engine by (16 points)

1 Answer

0 votes

The "body entered" signal is only emitted once, right when the checker touches the square for the first time. That's why by the time you release the mouse button, there's no event triggering the repositioning.

Also, I'd assume the checker can touch more than one square at the same time, so I'd rather check for the mouse than for the checker touching the square.

Assuming your tree looks like this:

- Square
- Checker

1) Create a variable "target_square" in Main.gd

2) In Square.gd:

func _on_Square_mouse_entered():
    get_parent().target_square = self

func _on_Square_mouse_exited():
    if get_parent().target_square == self:
        get_parent().target_square = null

3) Change inputevent in Checker.gd as follows:

func _input_event(viewport, event, shape_idx):
    if event is InputEventMouseButton:
        # snap to target square if released next to it
        var ts = get_parent().target_square
        if can_grab and !event.pressed and is_instance_valid(ts):
            global_position = ts.global_position
        can_grab = event.pressed
        grabbed_offset = position - get_global_mouse_position()
by (1,742 points)
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.