+1 vote

Hi guys, basically i have these scene:

  1. Cat | KinematicBody2D
  2. Train Cart | Note2D that contains 3 sprite representing 3 cart with each cart call Cart Area2D scene below
  3. Cart Area2D | Area2D with CollisionShape2D, basically representing the collision area of each cart
  4. Main | 3 Cat, 1 Train Cart

The game goal is to put each Cat to the correct Train Cart based on color with touch screen control. My problem now is that i want to move the Train Cart when each cart already contains the correct Cat. But i can't seem to found how the Train Cart can detect if each Cart Area2D already contain the correct cart.


My empty code is like this

func _on_Area2D_body_entered(body):
    #if correct cat entered +1
    pass


func _on_Area2D_body_exited(body):
    #if correct cat exited -1
    pass

func _process(delta):
    #if all cart contains correct cat, move cart
    pass

I've set up color variable in my Cat and i know that i can get the cat color by doing body.color, but how to get the Cart Area2D color that triggers the signal?. Or there's better way to do this?

Thanks!

Godot version 3.3.2
in Engine by (20 points)
edited by

3 Answers

0 votes
Best answer

I use the others suggested method with _on_Area2D_body_entered and _on_Area2D_body_exited connection but that result in the train immediately move without waiting the cat to snap to the cart position. Since the signal emitted once the Cat touched the Area2D

After some trial and error i found the best way to do this the way i intended. I create a function in my Cart that can be called by the Cat

extends Area2D

var color = "Pink"
var hasCorrectCat = false
signal cart_changed

func correct_cat_in_cart():
    #when called mark that correct cat in cart
    hasCorrectCat = true
    emit_signal("cart_changed")

In my code i have the cat quickly snap to cart position when the user release their touch control. So i call correct_cat_in_cart()when the user release their touch and this ensure the cat to snap to the cart first before the train moves.

by (20 points)
+1 vote

I would make your problem a little easier by changing your Train Cart node into a Train node that has 3 Train Cart nodes as children of it. Then in your Train Cart nodes do something like this:

 # Train_Cart.gd
extends Area2D

signal cart_changed

var correct_color = 'blue' # or however you're keeping track of the colors
var has_correct_cat = false

func _ready():
    self.connect("body_entered", self, "_on_Area2D_body_entered")
    self.connect("body_exited", self, "_on_Area2D_body_exited")

func _on_Area2D_body_entered(body):
    if body.color == correct_color:
        has_correct_cat = true
   emit_signal("cart_changed")

func _on_Area2D_body_exited(body):
   has_correct_cat = false
   emit_signal("cart_changed")

Then the rest of the logic is handled in your singular parent Train node:

 # train.gd
extends Node2D # or whatever you think it should be

func _ready():
    for train_cart in get_children():
        train_cart.connect("cart_changed", self, "_on_cart_changed")

func _on_cart_changed():
    for train_cart in get_children():
        if not train_cart.has_correct_cat:
            return # if one cart doesn't have the correct cat just drop out of the function
    # if we got here, all carts have the correct cat
    # so place the logic to move your train here
by (3,389 points)

That clears things up. I somehow doesn't even have any script on the Train Cart node, so signaling from the Cart nodes to the Train nodes really solve my problem. I made this game for my daughter, me and her both thank you!

edit: after trying this and played around with it turns out this doesn't work as i intended and produce a funny bug where the train moves without the cat.

0 votes

A simpler way to do it would be to put the cats in a group and get their color, which should probably be a string. then you could do this:

func _on_Area2D_body_entered(body):
    if(_body.is_in_group("cats"):
        if(body.color == correct_color):
            correct_cat = true;

func _on_Area2D_body_exited(body):
    if(_body.is_in_group("cats"):
        if(body.color == correct_color):
            correct_cat = false;
by (47 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.