why my animationPlayer massup when i press 2 or 3 button at same time?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By potatobanana

when i press up and left/right at same time while my character face down, my character will moonwalk to up right. or when i press left+up then +right and release left, my character start to moonwalk to right , my character play animationplayer move_Left over move_Right.
sorry for my broken eng.

extends KinematicBody2D

const move_speed = 100
var move_direction = dir.center
var sprite_direction = "_Down"


func _physics_process(delta):
	control_loop()
	move_loop()
	sprite_loop()
	if move_direction != dir.center:
		animation_play("Fmove")
	else:
		animation_play("Fidle")
	
	
	pass

func control_loop():#control key
	var RIGHT = Input.is_action_pressed("ui_right")
	var LEFT = Input.is_action_pressed("ui_left")
	var DOWN = Input.is_action_pressed("ui_down")
	var UP = Input.is_action_pressed("ui_up")
	############Walking##################
	move_direction.x = int(RIGHT) -int(LEFT)
	move_direction.y = int(DOWN)  -int(UP)



func move_loop():
	var motion = move_direction.normalized() * move_speed
	move_and_slide(motion, dir.center)
	
	


func sprite_loop():
	match move_direction:
		dir.right:
			sprite_direction ="_Right"
		dir.left:
			sprite_direction = "_Left"
		dir.up:
			sprite_direction = "_Up"
		dir.down:
			sprite_direction = "_Down"
:bust_in_silhouette: Reply From: nooberdev

Judging from your code-snippet, you can walk diagonally too, but you only assigned 4 directions to your spriteloop.
You either add additional conditions for diagonal movement or you completely switch to 4 direction movement.

Conditions for diagonal movement would be (keep everything as is, but add 4 extra conditions to your spriteloop):

if dir.right and dir.up:
    sprite_dir = "up" # or right, depends on your preference
if dir.right and dir.down:
    sprite_dir = "down" # or right, again your preference what you like more

Or you switch to 4 way movement instead of 8 with the following code example (just switch out input code, keep everything else as is):

func get_input():
	velocity = Vector2()
	if Input.is_action_pressed("ui_right"):
		velocity.x += 1
	elif Input.is_action_pressed("ui_left"):
		velocity.x -= 1
	elif Input.is_action_pressed("ui_down"):
		velocity.y += 1
	elif Input.is_action_pressed("ui_up"):
		velocity.y -= 1
	movement = velocity.normalized() * speed

and have your process set up like

func _process(delta):
	get_input()
	move_and_slide(movement)

The second version is what I have switched to in my game. It fits more to the retro arcade style I try to follow, where you only could walk in 4 directions.
Would be nice if you could report back if this helped.

thank you for your answer,
if you want to use 4 direction use this code u just need to put if move_direction.y == 0: and if move_direction.x == 0: like this :

func control_loop():#control key
	var RIGHT = Input.is_action_pressed("ui_right")
	var LEFT = Input.is_action_pressed("ui_left")
	var DOWN = Input.is_action_pressed("ui_down")
	var UP = Input.is_action_pressed("ui_up")
	############Walking##################
	if move_direction.y == 0:
		move_direction.x = int(RIGHT) -int(LEFT)
	if move_direction.x == 0:
		move_direction.y = int(DOWN)  -int(UP)

i understand what your meant in 8 direction, but if i put your code under func _physics_process my idle always facing down. and i dont how to put “if” in match.

potatobanana | 2018-08-07 05:41

The code you provided for 4-way movement is good too. :slight_smile:

You can keep the conditions within a match statement too, gets the job done to prevent moonwalking. Or you make it a feature in your game and make it a Michael Jackson game. (just kidding)

Right now the code does the following:
Press Left + Up makes the direction to Vector2(-1,-1), which is not set for spritedirection, so it takes the first one in your sprite_loop that fits the criteria, which is sprite_left. If sprite.dir up would be before left in your match statement, the character would walk up instead of left.
If you now press Right and release Left, the Vector becomes Vector2(1,-1), which is again not set as direction, so the sprite_loop keeps the previous direction as is and does not trigger any condition.

To illustrate, I edit your code as an example and keep it as similar as you use it. This way you dont have to change much in your code (no crazy if/elif blocks):

func sprite_loop():
	match move_direction:
		dir.right:
			sprite_direction ="_Right"
		dir.left:
			sprite_direction = "_Left"
		dir.up:
			sprite_direction = "_Up"
		dir.down:
			sprite_direction = "_Down"
		dir.upleft:# equals Vector2(-1,-1) when you press up AND left
			sprite_direction = "_Left"
		dir.upright:# equals Vector2(1,-1)
			sprite_direction = "_Right"
		dir.downleft:# Vector(-1,1) I think you got the idea
			sprite_direction = "_Left"
		dir.downright:# Vector2(1,-1)
			sprite_direction = "_Right"

hope this helps.

nooberdev | 2018-08-07 10:10

omg, thank you so much, lol i totally forgot about Vector2, i spent 5 day to solve this problem yet not even remember Vector2. when you first reply to me i was like this good idea must work then i was like dir.up + dir.left = vector2(-1,-1). lol. you save my day, thanks.

extends Node

const center = Vector2(0,0)
const right = Vector2(1,0)
const left = Vector2(-1,0)
const up = Vector2(0,-1)
const down = Vector2(0,1)
const upLeft = Vector2(-1,-1)
const upRight = Vector2(1,-1)
const downLeft = Vector2(-1,1)
const downRight = Vector2(1,1)

func random():
	var d = randi() % 9 + 1
	match d:
		1:
			return center
		2:
			return right
		3:
			return left
		4: 
			return up
		5:
			return down
		6: 
			return upLeft
		7:
			return upRight
		8: 
			return downRight
		9:
			return downLeft

i have one question, did godot have point direction func like from(x,y) ,to (x,y)?

potatobanana | 2018-08-07 13:17

Glad I could help! :slight_smile:

i have one question, did godot have point direction func like from(x,y) ,to (x,y)?

Can you rephrase the question or give an example? Do you want a Vector pointing towards an object on the screen? If yes: Vector math — Godot Engine (latest) documentation in English

You just subtract your position from the desired position and get a Vector in return that points from your position to your target.

Example:
VectorToTarget = MyPosition - TargetPosition
I hope I understood you correctly

nooberdev | 2018-08-07 14:16

yes , Vector pointing towards an object on the screen. thank you.
can i bother future? if i have some with godot?

potatobanana | 2018-08-07 18:50

I’d suggest creating a thread in the forums, so others who have the same issues can find answers. I am a beginner myself and dont know everything. But if you want to chat about game dev stuff, you can message me on twitter. My username is @nooberdev

nooberdev | 2018-08-08 16:54

i will make thread when i finish this project, so i can answer q. ill make twitter then.

potatobanana | 2018-08-09 09:51