Hello there. I’m trying to learn the engine by creating my very own clone of Flappy bird. All was going smoothly until I ran into an issue with collision detection. So my bird is a CharacterBody2D and the pillars which the bird has to avoid are StaticBody2Ds. I’ve used move_and_collide to check for collisions and it works to a certain extent. The collision detection works for the bottom and top of the pillars but not for the left and right sides. The result being that when the bird falls or touches the top/bottom side of the pillar, game over occurs and when the bird touches the left/right side of the pillar, the bird moves along with the pillar because it’s being pushed and game over does not occur. Note that the bird’s x position is locked while the y position changes for flight and that the pillars move in the left direction. How do I get collision detection to work for the left/right side as well? Or is there any other option?
Pillar code-
func _process(delta: float) -> void:
velocity.x = speed * delta
position += velocity
if position.x < -400:
queue_free()
Player code-
func _process(delta: float) -> void:
velocity.y += gravity * delta
if Input.is_action_just_pressed("fly"):
velocity.y = jump_speed
var collision = move_and_collide(velocity * delta)
if collision:
pillar_hit.emit()
Firstly you should be using the _physics_process function to move the physics objects like player and pillar.
Secondly, you’re using the move_and_collide function which is inherited from PhysicsBody2D and not implemented in CharacterBody2D. Try the move_and_slide function. The odd behavior you’re experiencing might be due to these two steps.
Oh you’re right. I looked at the doc page for CharacterBody2D and it didn’t mention move_and_collide but that’s because it’s inherited. Anyways I still think it’s a good idea to try using the other function and see if you get a different result.
I get it now after looking through the code again. You’re only moving the pipes and not the bird on the horizontal axis, meaning the player never checks for collisions along that axis. You can fix this by calling a function from the pipes on the player when the collision occurs. Although you’re also using StaticBody2D which is not intended to be moved. Change it to AnimatedBody2D.
I believe that the problem is that the pillar is moving horizontally, not the player. Because of that, it’s the pillar that collides with the player, not the other way around.
IMO, the proper way to fix this would be to change it so the player moves and not the pillar. The quick and dirty fix would be to call move_and_collide with an horizontal speed, and setting the test_only parameter to true. With this parameter, you can detect collisions without moving. More details here: PhysicsBody2D — Godot Engine (stable) documentation in English
On another note, I suggest you to read about VisibleOnScreenEnabler2D. It would help you despawning nodes outside the screen
You’re right. I tested it out nd horizontal collision detection works when the player collides with the pillar
It is simpler to have a static camera and player instead of a moving one. So I’d like to continue with my current arrangement unless there is no other option.
Thanks for the suggestion. I didn’t even consider using that node.
It’s the exact same as move_and_collide, however it’s not really relevant to your problem because the player doesn’t move horizontally anyways. You can fix this in a bunch of ways, one of them being mentioned above by henridd, and I’ll explain another right now.
Add an Area2D or AnimatableBody2D with the same radius as the player and use it as a Hitbox. Once the pillar moves, it’ll move into the Area or AnimatableBody Hitbox, both of which will register the collision and report it. The downside of Area2D is that you won’t have any collision info reported, only that there has been a collision.