Need Help Understanding How to Block Movement

Version 4.2.2

Hi everyone,

I can understand how to use CollisionShapes and code to detect when an object is touching another object, which I succesfully did already in my Flappy Bird game on my “Need Help with Timer Not Acting Properly” thread,

But I need help understanding how to prevent an object from moving on another object, like I want to block the first object completely from moving on the second object, like a wall, which is exactly why I am doing this - I am making a Pacman game with my own twist to it to avoid copyright infringement, and I want it so that you can’t go on the walls period, rather than them knocking you back when you touch them, which would look sloppy/awkward.

Does anyone know the correct way to do this, whether using code or just the built-in features in the editor?

Thank all of you in advance.

I would use a characterbody2d. Use the default script template. But remove gravity and jumping. Just keep the direction. (You will also need to add an up/down as it will only handle left/right out-of-the-box.

Thats it. It will collide and stop dead without bouncing. And you can begin to tweek it to fit your needs.

Awesome! Thank you for the helpful suggestion.

If I am to understand correctly, it will collide automatically with the walls without needing a CharacterBody2D for the wall object once I do what your directions are exactly, or is there something else I need to add after?

Your walls should use StaticBody2D with a collision shape. A StaticBody2D will automatically prevent a CharacterBody2D (or other body types) from moving into it, as long as you move the CharacterBody2D using its built-in move_and_slide or move_and_collide methods.

1 Like

Awesome! Thank you for that - the game should work flawlessly, but I haven’t actually tested it yet, I am just hoping it works well.

Hi, unfortunately I did what you said about adding a StaticBody2D on the walls as well as a CharacterBody2D on the player, but sadly it doesn’t collide with the default move and slide in the script, and when I tried move and collide I get told I need at least 1 argument/input, and I don’t know what I should add in the parenthesis.

I am uploading and attaching my game so far so everyone can see exactly what is wrong.

The CharacterBody2D is supposed to be the root node of the player scene. With the way you’ve set it up now, you have two different nodes that move when the player presses buttons.

Here’s player.tscn with a CharacterBody2D as the root node:
image

And here’s the script for it, which replicates the behavior from your old player.gd script, but using move_and_slide()

extends CharacterBody2D

var moving_direction = Vector2(1, 0)
const SPEED = 400.0

func _process(delta: float) -> void:
    $AnimatedSprite2D.play()	
    $AnimatedSprite2D.animation = "eat"
    
    if Input.is_action_pressed("move_left"):
        $AnimatedSprite2D.flip_h = true
        rotation = 0
        moving_direction = Vector2(-1, 0)
    if Input.is_action_pressed("move_right"):
        $AnimatedSprite2D.flip_h = false
        rotation = 0
        moving_direction = Vector2(1, 0)
    if Input.is_action_pressed("move_down"):
        $AnimatedSprite2D.flip_h = false
        rotation = PI / 2
        moving_direction = Vector2(0, 1)
    if Input.is_action_pressed("move_up"):
        $AnimatedSprite2D.flip_h = false
        rotation = (3 * PI) / 2
        moving_direction = Vector2(0, -1)

func _physics_process(delta):    
    velocity = moving_direction * SPEED
    move_and_slide()

Awesome! Thank you for the easy fix.

Now it works flawlessly, except that it slides around the object when touching a corner which is expected of move_and_slide, so what is the proper syntax for using the move_and_collide without sliding?

Because the original Pacman didn’t slide around corners at all, and I want to keep it that way

move_and_collide(velocity * delta) I think.

Great! Thank you so much!

It works 100% perfectly now - I think finishing the rest of the game will be smooth sailing, because I have the Flappy Bird game that works perfectly, and it has all the things I need I learned, like how to instantiate/generate a scene in a scene, how to make proper transitions with tweens and so on.

I might need help with AI for enemies, but I think it will just be a simple matter of using tons of “if-else” blocks and checking for distance.

1 Like

Okay, actually I do need help with something - for the CharacterBody2D that you said I needed to change the player to, it seems under the Signals list there isn’t an “area_entered” signal, unlike Area2D, and I want it to pick up mushrooms in the same way as it picks up the Pacman dots, so not colliding with it in the same way as it does for the wall StaticBody, and the mushrooms disappear as soon as the collision is entered.

What is the appropriate code I should use instead?

Thank you guys in advance.

Link to Latest Download

Two options:

  • Give the player an Area2D as a child node
  • Make the mushroom an Area2D, and use its body_entered signal to detect the player - this way, it’s the mushroom detecting that it’s getting eaten, rather than the player detecting the mushroom.

I already have the mushroom as an Area2D - so that’s probably the solution I am gonna use. Thank you as always!

1 Like

Okay, so now I have this version of my Pacman game all in a ZIP ready for everyone to review:

Pizza Panic Game Without Sound Working Correctly

My problem now is that even though I used the Flappy Bird game I made on the other thread I started, which has functional sound, for reference, the sound doesn’t play at all even though I imported it and called it in the code in the appropriate place in the same way - the only catch is that the AudioStreamPlayer is a child of an instantiated scene, the mushroom, and not the main game node.

Do you guys think this might be what causes the sound to not play in-game even though I test it plays correctly in the editor, or am I missing another piece of code or other thing I need to in the editor first?

Thank you very much in advance.

Nah, the problem is that you’re deleting the whole mushroom (and thus also the AudioStreamPlayer, since it’s a child) immediately.

Lazy solution:

func _on_body_entered(body):
    if body is Player:
        $ChompSound.play()
        hide()
        await $ChompSound.finished
        queue_free()

A better solution would be to play the sound from a node that isn’t gonna get deleted. The problem with the lazy solution is that, theoretically, the player could manage to enter the area a second time before the mushroom gets properly deleted, thus scoring double points or whatever (if you add a point system at some point).

Awesome! Thank you so much as always! I figured that might have been the problem, but thought it would play the sound before deleting but apparently it doesn’t, but your fix will address that.