- Edited
One method is to convert the direction vector to an angle, and then round it to the nearest multiple of 90 degrees. Then convert the result back to a vector for the velocity calculation.
One method is to convert the direction vector to an angle, and then round it to the nearest multiple of 90 degrees. Then convert the result back to a vector for the velocity calculation.
You could just logic a new Vector2 from the inputs.
var ndir : Vector2 = Vector2.ZERO
if direction.x > 0.0:
ndir = Vector2.RIGHT
elif direction.x < 0.0:
ndir = Vector2.LEFT
elif direction.y > 0.0:
ndir = Vector2.UP
elif direction.y < 0.0:
ndir = Vector2.DOWN
It's not elegant but not everything has to be.
Jesusemora
so like this
func _physics_process(delta):
var direction = Input.get_vector("left","right","up","down")
if direction:
velocity = direction*SPEED
else :
velocity = Vector2.ZERO
var ndir : Vector2 = Vector2.ZERO
if direction.x > 0.0:
ndir = Vector2.RIGHT
elif direction.x < 0.0:
ndir = Vector2.LEFT
elif direction.y > 0.0:
ndir = Vector2.UP
elif direction.y < 0.0:
ndir = Vector2.DOWN
move_and_slide()
player still moves diagonally tho
var direction = Input.get_vector("left","right","up","down")
This gets all the input vectors when you simply don't want that; if you want to move in a single direction, it needs to be mutually-exclusive, e.g. if the player is going left, then only move them left. If they're not going left, then you can check the other input vectors. You can get input vectors one-at-a-time.
The code posted above is almost there. Do you think this:
if direction:
velocity = direction * SPEED
else:
Is necessary?
DaveTheCoder
how do you do that exactly ?
if Input.is_action_pressed("right"):
velocity = snapped(Vector2.RIGHT.angle() , 90)* SPEED
something like this?
spaceyjase
var direction = Input.get_vector("left") or Input.get_vector("right")
this is not something i can do right?
or maybe
var direction = Input.get_axis("left") or Input.get_axis("right")
Folivora Simple mutual exclusion always feels wonky. Here's how it should be done in the most player-friendly way:
var pressed_actions = []
const directions = { &"ui_left": Vector2(-1, 0), &"ui_right": Vector2(1, 0), &"ui_up": Vector2(0, -1), &"ui_down": Vector2(0, 1) }
func _process(delta):
for d in directions:
if Input.is_action_just_pressed(d):
pressed_actions.push_back(d)
if Input.is_action_just_released(d):
pressed_actions.erase(d)
var direction = Vector2.ZERO if pressed_actions.is_empty() else directions[pressed_actions[-1]]
print(direction)
If multiple actions are pressed is will use the one that was pressed last, and if one of the actions is released while one or more actions are still held, it will use the one that was pressed last among the still held actions. This feels very natural and pleasant to the player.
Folivora It's a definition of a dictionary (aka associative array) that maps action names to corresponding direction vectors. I used default action names for arrow keys, you can replace them with your own names.
xyz
is this what i should be left with
`var pressed_actions = []
const directions = { "left" : Vector2(-1, 0), "right": Vector2(1, 0), "up": Vector2(0, -1), "down": Vector2(0, 1) }
func _process(delta):
for d in directions:
if Input.is_action_just_pressed(d):
pressed_actions.push_back(d)
if Input.is_action_just_released(d):
pressed_actions.erase(d)
var direction = Vector2.ZERO if pressed_actions.is_empty() else directions[pressed_actions[-1]]
print(direction)
func _physics_process(delta):
if directions:
velocity = directions * SPEED
else :
velocity = Vector2.ZERO
move_and_slide()
if velocity == Vector2.ZERO:`
Folivora you were supposed to use ndir
for movement instead of direction
.
Well it is solved now.
DaveTheCoder One method is to convert the direction vector to an angle, and then round it to the nearest multiple of 90 degrees. Then convert the result back to a vector for the velocity calculation.
Folivora how do you do that exactly ?
const HALF_PI: float = PI / 2.0
var new_direction: Vector2 = Vector2.from_angle((roundf(direction.angle() / HALF_PI)) * HALF_PI)
Here's a demo of the code I posted:
https://davethecoder.itch.io/zigzag
DaveTheCoder That's grid based. I think OP asked specifically for non-grid, continuous movement.
It's not grid-based, unless I misunderstand what that means.
DaveTheCoder Looks pretty grid-y to me When I press the key once the circle instantly steps for a distance that's roughly its size.
The distance moved is determined by a speed constant.
That's only a quick demo for using the code I posted above. I guess it could be made smoother, but I wasn't trying to do that.
The full code is here: https://github.com/daveTheOldCoder/zigzag
DaveTheCoder Ok, but the example you posted still behaves quite unpleasantly. It has a keyboard echo delay, behaves badly when multiple keys are pressed and doesn't continue to move when a key is released but another key is still pressed. Try to run my example to see what exactly I mean.