# How do i change direction with collisions? (Solved)

Attention Topic was automatically imported from the old Question2Answer platform.

I want to change direction on the x axis whenever`is_on_wall`.

I almost got it…

``````extends KinematicBody2D

const UP = Vector2(0, -1)
const GRAVITY = 20

var motion = Vector2()
var left = Vector2(-1, 0)
var right = Vector2(1, 0)

func _physics_process(delta):
motion.y += GRAVITY
motion = move_and_slide(motion, UP)
position += left

if is_on_wall():
if left == left:
left = right
if right == right:
right = left
``````

Now whenever i hit a wall going left it will start moving right, but hitting a wall while moving right still makes it wants to keep moving right?!

KND2501 | 2018-03-09 23:25

UPDATED && OPTIMIZED

``````extends KinematicBody2D

const UP : = Vector2(0, -1)
const GRAVITY : = 20
const SPEED : = 300

var motion : = Vector2.ZERO
var direction : = 1.0

func _physics_process(delta: float) -> void:
motion.y += GRAVITY
motion.x = direction * SPEED
motion = move_and_slide(motion, UP)

if is_on_wall():
direction*=-1
``````

To get autocompletion for this func _physics_process(delta: float) → void
go to editor settings >search for “add type hints” click “ON”

In the code provided in your comment, you overwrite your directional vector. You should introduce another vector, which is either left or right depending on current movement.

``````var move = left

func _physics_process(delta):
...
position += move

if is_on_wall():
if move == left:
move = right
elif move == right: #note the elif instead of if
move = left
``````

btw, why are you changing position directly? That’s what move_and_slide() is for. You should update your motion.x.

You should note i have no idea what i’m doing.

I’m changing position directly because its movement is not controlled by inputs, otherwise it just sits till.

So i am looking at your example, changed the `var move` to `var direction` . But it does exactly the same as what i had before.

``````extends KinematicBody2D

const UP = Vector2(0, -1)
const GRAVITY = 20

var motion = Vector2()
var left = Vector2(-1, 0)
var right = Vector2(1, 0)
var direction = left

func _physics_process(delta):
motion.y += GRAVITY
motion = move_and_slide(motion, UP)
position += direction

if is_on_wall():
if direction == left:
direction = right
print("AAAA")
elif direction == right:
right = left
print("BBBB")
``````

KND2501 | 2018-03-10 00:17

You should note i have no idea what i’m doing.

Well, I’m not sure what you are trying to achieve too xd

What I mean by changing motion is something like this:

``````motion.y += GRAVITY
motion.x = direction.x
``````

Then you should be able to move without changing position manually.
So, what exactly is the problem you have? I didn’t test the code, but seems like it should work with these changes. What is the output from print?

KoBeWi | 2018-03-10 00:41

Basically i am making a Goomba.

Kinematicbody2D just starts moving in a set direction (left), and whenever it hits a wall it changes direction until it hits another wall and changes direction again etc.

So far i got it to move and change direction from left to right upon collision with the wall.

The problem is having it change direction from right to left and i think it has got to do with the initial motion.

KND2501 | 2018-03-10 00:59

OMG. I just noticed you made a mistake in your code. You still have right = left after elif. It should be direction = left.

KoBeWi | 2018-03-10 01:18

Not a mistake, if i change it to `=left` it actually starts bouncing in the corner. If i change the other one to `=right` then its just stuck in the corner.

The `direction` variable doesn’t seem to work, i can achieve the same result i have now with less code. If i go back to this (i simplified it a bit) then i’m almost there:

``````position += left

if is_on_wall():
if left:
left = right
print("AAAA")
elif right:
right = left
print("BBBB")
``````

But it won’t return my `print("BBBB")` because it’s always going `position += left` i think.

KND2501 | 2018-03-10 01:40

Ok, I made a test game specifically for this. Here’s the working code:

``````extends KinematicBody2D

const UP = Vector2(0, -1)
const GRAVITY = 20
const SPEED = 100

var motion = Vector2()
var left = Vector2(-1, 0)
var right = Vector2(1, 0)
var direction = left

func _physics_process(delta):
motion.y += GRAVITY
motion.x = direction.x * SPEED
motion = move_and_slide(motion, UP)

if is_on_wall():
if direction == left:
direction = right
elif direction == right:
direction = left
``````

Now, what you do with left = right and right = left is totally wrong. Here’s what happens in your code:
-game starts, object moves left (-1, 0)
-object meets a wall, so the left is now right (1, 0)
-it meets another wall, and now, what it actually does is right = right.

That is because you modify your original vector. Remember that if you make a var in your object, modifying it will modify the original (if I’d want to explain it clearly). So doing left = right will permanently overwrite left, so it is now right. That’s why doing right = left then is basically making the variable assign itself.

Also, my code works, because you need to use move_and_slide() to determine whether something is on the wall. If you move only vertically, you are never on wall, so your is_on_wall() should always be false.
I don’t know how your original code worked (it didn’t for me), because when you hit the wall that way, you shouldn’t be able to bounce. The object just gets stuck (and is apparently pushed back by physics).

KoBeWi | 2018-03-10 02:03

Your code works! Yeah i saw a tutorial using a simular method to my right/left stuff, so i tried to adapt the code.

So yeah this is basically want i want, but i notice now it collides with the player as well, when before it would push me aside.

So before i used to move the “goomba” pixel by pixel, now i’m using physics right? What if i want to use pixel by pixel movement instead?

Thanx for thinking along btw.

KND2501 | 2018-03-10 02:19

Well, I never used pixel-by-pixel movement in Godot, so I don’t know how to handle collisions.

If you don’t want your Goomba to collide with player, modify their collisions layers. There’s a property in KinematicBody2D in inspector that let’s you change this. If they have collision layer 1 turned off, it means that nothing can collide with them, but they will still collide with environment if their collision masks are turned on.

KoBeWi | 2018-03-10 13:33

Actually i turned goomba in a bunny rabbit, just hopping around no collision.

What i meant was your method seems to interact with physics, while the other would override physics and just push through. That be nice for moving platforms.

Anyway thanx.

KND2501 | 2018-03-11 02:25

Solution by KoBeWii

``````extends KinematicBody2D

const UP = Vector2(0, -1)
const GRAVITY = 20
const SPEED = 100

var motion = Vector2()
var left = Vector2(-1, 0)
var right = Vector2(1, 0)
var direction = left

func _physics_process(delta):
motion.y += GRAVITY
motion.x = direction.x * SPEED
motion = move_and_slide(motion, UP)

if is_on_wall():
if direction == left:
direction = right
elif direction == right:
direction = left
``````