Need HELP understanding Signals/Collisions

I think I might have also played this game lol, or a version of it.

The on_body_entered signal passes the collided body as a parameter.
So if you connect the player’s area2D on_body_entered signal, the collided body should be the enemy if you setup your collision layers/masks properly.
fish_game

In this case, the enemy doesn’t even need to have a Area2D, just the player will do:

image
One thing to note is that the area2D for the player needs to be a bit bigger than the actual collision shape so it can detect properly.
image

And it’s a very simple player script:

extends CharacterBody2D


const SPEED = 300.0


func _physics_process(_delta: float) -> void:
	# Get the input direction and handle the movement/deceleration.
	# As good practice, you should replace UI actions with custom gameplay actions.
	var direction := Input.get_vector("ui_left", "ui_right", "ui_up", "ui_down")
	
	if direction != Vector2.ZERO:
		velocity = direction * SPEED
	else:
		velocity = Vector2.ZERO
	move_and_slide()


func _on_area_2d_body_entered(body: Node2D) -> void:
	print("Enemy Scale : %.2f" % body.transform.get_scale().x)
	print("Player Scale: %.2f" % body.transform.get_scale().x)
	
	# Player area collides with self
	# Use this if, or change the collision layer/mask
	if body == self:
		return
	
	if scale.x > body.scale.x:
		# Can eat
		body.queue_free()
		## Increase player size
		scale *= 1.1
	else:
		# Player eaten
		## Respawn()/ResetGame() code here
		print("Player eaten")
		queue_free()

This will work if all your fish sprites are the same sizes, and use the scale to make them bigger or smaller.

If you have bigger fishes with bigger sprites, then you might need to create a custom enemy class to store its ‘real size’ value, and check for that instead.

1 Like