Reputation: 21
Basically, I'm trying to make a character move in 8 directions, while only having diagonal sprites. How I plan for this to work is that the character has sprites facing the 4 diagonal cardinal directions, and if say, the character was facing southeast and starts moving south, the sprite wouldn't change. If the character was facing southwest, the same applies. If the character starts moving up from facing southeast, the sprite would face northeast, and if the character moves left from facing northeast, the sprite will face northwest. Same goes from southeast to southwest.
I tried implementing a sort-of vector-based solution, but It didn't actually change the sprites and just showed the UpLeft walking animation. I could still control it, but it didn't do what I wanted it to. Can someone show me a solution to this? Because I'm still a beginner at Godot, and as of now, I have no clue what else to do.
extends CharacterBody2D
const max_speed = 50
const accel = 1500
const friction = 400
var input = Vector2.ZERO
@onready var animation = $AnimationPlayer
func get_input():
input.x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
input.y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
return input.normalized()
func player_movement(delta):
input = get_input()
if input == Vector2.ZERO:
if velocity.length() > (friction * delta):
velocity -= velocity.normalized() * (friction * delta)
else:
velocity = Vector2.ZERO
else:
velocity += (input * accel * delta)
velocity = velocity.limit_length(max_speed)
move_and_slide()
func updateAnimation():
var direction = "_DownRight"
if Vector2(1, -1): direction = "_UpRight"
if Vector2.ONE: direction = "_DownRight"
if Vector2(-1, 1): direction = "_DownLeft"
if Vector2(-1, -1): direction = "_UpLeft"
if Vector2.ZERO:
animation.play("walk" + direction + "Idle")
else:
animation.play("walk" + direction)
func _physics_process(delta):
player_movement(delta)
updateAnimation()
Can anybody help me with this?
Upvotes: 0
Views: 941
Reputation: 40295
Let me get something out of the way: You are using constants in the conditionals of some of your if
statements. Since they are constants we don't need to execute the code to know what will happen.
In particular, know that if you pass a zero value to if
, it will evaluate as false
. That works for null
, but also for Vector2.ZERO
and any other zero value.
So here:
if Vector2.ZERO:
animation.play("walk" + direction + "Idle")
else:
animation.play("walk" + direction)
The execution flow will enter the else
branch.
And here:
if Vector2(1, -1): direction = "_UpRight"
The execution flow will never enter.
In general, you want to use variables in if
statements.
Now, since you read Input
, convert it to integer, returned normalized
, and set input
to the return value... There are nine possible values for input
:
(-0.707107, -0.707107)
(1.0, 0.0)
(-0.707107, 0.707107)
(0.0, -1.0)
(0.0, 0.0)
(0.0, 1.0)
(0.707107, -0.707107)
(1.0, 0.0)
(0.707107, 0.707107)
Now, the direction needs to be updated based on that.
Since you only have the diagonals, we can only be sure of those:
(-0.707107, -0.707107) -> "_UpLeft"
(1.0, 0.0)
(-0.707107, 0.707107) -> "_DownLeft"
(0.0, -1.0)
(0.0, 0.0)
(0.0, 1.0)
(0.707107, -0.707107) -> "_UpRight"
(1.0, 0.0)
(0.707107, 0.707107) -> "_DownRight"
For the cases a 0.0
zero component, from your description, you do not want to change the direction... But the direction might still change based on the other component.
That means two things:
So, declare, near the top of the script, two variables:
var direction_h := ""
var direction_v := ""
Here I'm using _h
and _v
for horizontal and vertical, respectively.
I'll go with "Down" and "Right" for their default value, since they seem to be the default for you:
var direction_h := "Right"
var direction_v := "Down"
And now we can write this in updateAnimation
:
if input.x < 0.0:
direction_h = "Left"
elif input.x > 0.0:
direction_h = "Right"
if input.y < 0.0:
direction_v = "Up"
elif input.y > 0.0:
direction_v = "Down"
var direction := "_" + direction_v + direction_h
if input == Vector2.ZERO:
animation.play("walk" + direction + "Idle")
else:
animation.play("walk" + direction)
Upvotes: 0