#how to move constantly on a grid

45 messages · Page 1 of 1 (latest)

lyric needle
#

hello! I'm a 3D art student and I'm making a 2D game for class (3D models -> 2D sprites). It's basically snake but you play as a kid collecting bugs that follow you. I need the player character to be constantly moving in the last direction that was input. I have the grid based movement down but I can't get the player to stay in motion. The solutions I've found require a velocity function which I'm not using and I'm also not a programmer so I'm unsure if I'm searching the right stuff. I've gone through video tutorials and the documentation but it either isn't helpful or I don't understand what it means. I tried using a timer to continuously call the movement input but that didn't work. I followed a tutorial to constrain the movement to a grid but again, not a programmer, so I don't fully understand what everything does. I have a movement variable set to false but when setting it to true I can't move at all so I'm really stumped.

the input is is_action_pressed rn but I'll change it to is_action_just_pressed once the player stays in motion (I think)

how do I get the player to continuously move? pls explain like I'm 5.

chilly wagon
#

Set the velocity of the character then call move_and_slide(). No need to do a tween or call a separate move() function.

#

Basically, remove the move() function call from each of the conditions, then at the bottom just before move_and_slide() do something like velocity += input_dir * tile_size (maybe).

If you can attach a video to show what it is currently doing and then say what you actually want it to do that may be some help.

#

Not following what "continuous movement on a grid" means.

lyric needle
#

sorry about the quality, had to compress it, i don't have nitro. also ignore the ugly bg it's just a place holder

i need the player to keep walking forward but stay in the squares.

#

they currently stay on the squares but stop moving when the input isn't being pressed and i understand why that's happening. i want to be able to press an input and have the player keep moving in that direction but only in the grid

chilly wagon
#

Ah, gotcha. Try removing the move_and_slide() call. You also likely don't want to reset the input_dir to Vector2.ZERO every physics frame because the tween is using that to know where to move to.

#

So you likely want to change input_dir to Vector2.ZERO when you set moving = false

lyric needle
#

so instead of Vector2(x,y) it should be Vector2.ZERO for each one?

chilly wagon
#

No, I think the problem is that you reset it to Vector2.ZERO on every physics frame. Then you check if they are pressing a key and update the input direction.

Since the input_dir is a global variable that is being referenced rather than a local variable being passed into the move() function call, when you change it you are also changing (potentially, I'd have to check this) the position that is being tweened to.

#

So when you let go of the key, it tweens to nowhere because the input_dir is now Vector2.ZERO which means it's not going to move anywhere based on the math there.

#
extends CharacterBody2D

const TILE_SIZE = 200
var moving := false

@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D

func _physics_process(_delta: float) -> void:
  if Input.is_action_just_pressed("down"):
    animated_sprite_2d.play("down")
    move(Vector2(0, 1))
  # Do other statements here

func move(dir: Vector2) -> void:
  if moving:
    return

  moving = true
  var tween = create_tween()
  tween.tween_property(self, "position", position + dir * TILE_SIZE, 0.5)
  tween.finished.connect(fn () ->
    moving = false
  )

^- something like that may also work

#

Basically, if they just pressed a button, call move(dir_to_move) and then that function does the actual tween of the character.

The direction it is tweening to won't change because the function will immediately return out if it is currently moving.

lyric needle
#

doesn't seem to work, but i might've missed something

#

got the errors to go away but now it just crashes with any input

chilly wagon
#

Sorry, I had pseudo-code so it was going to require some tweaking to work.

What does your code look like right now and what is the error message when it crashes?

lyric needle
#

I undid too far and then couldn't redo, I don't know what I did to get the error messages to go away so this is where I'm at

#

I know I have to add a ) somewhere

chilly wagon
#

Try fixing the indentation on the next line.

#

Oh, also, the lambda was wrong there, should be uhh.

#

Or maybe not, give me a sec.

#
  tween.finished.connect(fn () -> void:
    moving = false
  )
#

^- I think that is the correct syntax.

lyric needle
#

hmm, doesn't look like it

chilly wagon
#

What's the new error?

lyric needle
chilly wagon
#

Your indentation isn't correct.

lyric needle
chilly wagon
#

Ahh, whoops, lol. Mixing languages. Needs to be func not fn. Let me get you code that doesn't have syntax errors in it. One sec.

#
extends CharacterBody2D

const TILE_SIZE = 200
var moving := false

@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D

func _physics_process(_delta: float) -> void:
    if Input.is_action_just_pressed("down"):
        animated_sprite_2d.play("down")
        move(Vector2(0, 1))
    elif Input.is_action_just_pressed("up"):
        animated_sprite_2d.play("up")
        move(Vector2(0, -1))
    elif Input.is_action_just_pressed("right"):
        animated_sprite_2d.play("right")
        move(Vector2(1, 0))
    elif Input.is_action_just_pressed("left"):
        animated_sprite_2d.play("left")
        move(Vector2(-1, 0))

func move(dir: Vector2) -> void:
    if moving:
        return

    moving = true
    var tween := create_tween()
    tween.tween_property(self, "position", position + dir * TILE_SIZE, 0.5)
    tween.finished.connect(func () -> void:
        moving = false
    )
lyric needle
#

the last ) is throwing a code

#

nvm, ran the game and it went away

chilly wagon
#

Add a new line at the end of the file

lyric needle
#

here is where I'm at, I can move but I don't keep moving. would adding a += 0.5 on the position work?

chilly wagon
#

AKA you want to hold "left" and have the character move left 1 tile, then move left again 1 tile, that sort of movement?

lyric needle
#

i want to hit left once then the player moves left until i hit another input

chilly wagon
#

Ohhh. So like how Snake works, yeah? Haha.

lyric needle
#

yes exactly

chilly wagon
#

Gotcha. One sec, will tweak the code.

#

What does this do? It's similar to being your original implementation so I feel like the player is going to be able to be "redirected" mid-movement (so move off grid), but that depends on how tween works:

extends CharacterBody2D

const TILE_SIZE = 200
var moving := false
var move_dir := Vector2.ZERO

@onready var animated_sprite_2d: AnimatedSprite2D = $AnimatedSprite2D

func _physics_process(_delta: float) -> void:
    if Input.is_action_just_pressed("down"):
        animated_sprite_2d.play("down")
        move_dir = Vector2(0, 1)
    elif Input.is_action_just_pressed("up"):
        animated_sprite_2d.play("up")
        move_dir = Vector2(0, -1)
    elif Input.is_action_just_pressed("right"):
        animated_sprite_2d.play("right")
        move_dir = Vector2(1, 0)
    elif Input.is_action_just_pressed("left"):
        animated_sprite_2d.play("left")
        move_dir = Vector2(-1, 0)
        
    move()

func move() -> void:
    if moving:
        return

    moving = true
    var tween := create_tween()
    tween.tween_property(self, "position", position + move_dir * TILE_SIZE, 0.5)
    tween.finished.connect(func () -> void:
        moving = false
    )

lyric needle
#

yoooo!! that works!

#

what did you do?

chilly wagon
#

Made the move_dir a top-level variable again and then made it call move() on every physics frame.

#

If it's already moving, it doesn't do anything (meaning the old tween is still going based on the previous value), and then once it stops moving it then starts moving in whatever the new direction is (if one was set).