|
|
|
|
Reply From: |
SIsilicon |
I know the type of movement your talking about. And I believe I have a solution.
var moving = false
func _physics_process(delta):
if !moving:
var motion_vector = Vector2()
if Input.is_action_pressed("ui_up"):
motion_vector += Vector2( 0, -1)
if Input.is_action_pressed("ui_down"):
motion_vector += Vector2( 0, 1)
if Input.is_action_pressed("ui_left"):
motion_vector += Vector2( -1, 0)
if Input.is_action_pressed("ui_right"):
motion_vector += Vector2( 1, 0)
if motion_vector != Vector2():
#tile_size is the size of the tilemap in pixels.
var new_position = position + motion_vector * tile_size
#Yes. I'm assuming you have a Tween node as a child.
$Tween.interpolate_property ( self, 'position', position, new_position, 0.6, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
#That last method's fifth property is how long it takes to go from one tile to the other in seconds.
$Tween.start()
moving = true
#This function is connected to the tween node's tween_completed signal.
func _on_Tween_tween_completed(object, key):
moving = false
I know the answer looks like it has parts taking from your question. But that was intentional so that you could understand it.
SIsilicon | 2018-05-17 20:48
Thank you for your answer, Sisilicon.
Ertain | 2018-05-17 22:27
I tried the code, and it only moved my sprite once. Repeated key pressed did nothing.
Ertain | 2018-05-18 03:26
Are you sure? I put the exact same code in a test project and it works fine.
Have you connected that last function to the tween_completed
signal?
SIsilicon | 2018-05-18 15:13
Thank you for the clarification. I’ll connect the signals (it pays to actually read the code comments).
Ertain | 2018-05-18 15:28
Okay, it’s working, albeit barely. My character is quite slow, and collisions don’t work. Well, at least it’s a start. :-/
Ertain | 2018-05-18 20:34
Slow character?
Remember this line??
$Tween.interpolate_property ( self, 'position', position, new_position, 0.6, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
#That last method's fifth property is how long it takes to go from one tile to the other in seconds.
The fifth property is your character’s speed. Except the bigger it is, the longer it takes for them to go to the next tile.
SIsilicon | 2018-05-18 22:50
So a value of 1 means it takes 1 second to go to the next tile.
And a value of zero means you travel instantly.
SIsilicon | 2018-05-18 22:55
I eventually learned that. As for collisions, well, that’s another monster.
Ertain | 2018-05-18 23:52
I gotcha covered there.
Assuming your player is a kinematic body, you should have access to the method test_move(Transform2D from, Vector2 rel_vec)
. Returns true if a collision occurs.
Which mean you will change this-
#tile_size is the size of the tilemap in pixels.
var new_position = position + motion_vector * tile_size
#Yes. I'm assuming you have a Tween node as a child.
$Tween.interpolate_property ( self, 'position', position, new_position, 0.6, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
#That last method's fifth property is how long it takes to go from one tile to the other in seconds.
$Tween.start()
moving = true
To this.
#tile_size is the size of the tilemap in pixels.
motion_vector *= tile_size
if not test_move(global_transform, motion_vector):
#Yes. I'm assuming you have a Tween node as a child.
$Tween.interpolate_property ( self, 'position', position, position+motion_vector, 0.6, Tween.TRANS_LINEAR, Tween.EASE_IN_OUT)
#That last method's fifth property is how long it takes to go from one tile to the other in seconds.
$Tween.start()
moving = true
Notice that the new_position
variable was omitted and in the Tween’s function replaced with position+motion_vector
.
SIsilicon | 2018-05-19 00:22
Thank you for that fix, Sisilicon.
Ertain | 2018-05-20 02:16
extends KinematicBody2D
var motion = Vector2()
var talking = false
var move_speed = 50
var facing = "down"
func _physics_process(delta):
#<!-- CHECK TO SEE IF PLAYER IS TALKING --!>#
if talking != true:
#<!-- CHECK TO SEE IF PLAYER IS PRESSING A BUTTON --!>#
if Input.is_action_pressed("ui_right"):
facing = "right"
$Sprite.play("walk_right")
motion.y = 0
motion.x = move_speed
elif Input.is_action_pressed("ui_left"):
$Sprite.play("walk_left")
facing = "left"
motion.y = 0
motion.x = -move_speed
elif Input.is_action_pressed("ui_up"):
$Sprite.play("walk_up")
facing = "up"
motion.x = 0
motion.y = -move_speed
elif Input.is_action_pressed("ui_down"):
$Sprite.play("walk_down")
facing = "down"
motion.x = 0
motion.y = move_speed
else:
#<!-- IF THE USER IS NOT PRESSING THE BUTTONS SET PLAYER TO IDLE --!>#
if facing == "right":
$Sprite.play("idle_right")
elif facing == "left":
$Sprite.play("idle_left")
elif facing == "up":
$Sprite.play("idle_up")
elif facing == "down":
$Sprite.play("idle_down")
motion.x = 0
motion.y = 0
#<!-- MOVE PLAYER ON THE X AND Y AXIS--!>#
move_and_slide(motion)
pass
jack the programmer | 2019-04-15 23:39
Thank you all so much for this, it has been very helpful. I too got the single movement the first time I ran the code. After that it just worked. My issue is that if I hold down an arrow key, it makes the first move, stops, and then continues on. How do I make sure that the motion is smooth throughout?
Edit:
Nevermind I’m an idiot. I was playing the wrong scene
jackatthekilns | 2021-01-13 19:07