Hello,
i wrote the code, a little bit down, today on 3 Hours. I already get a bit lost when locking for Problems. The newest Problem is that the player cant jump, but because I wrote such spahgehtti code I wanted to ask if someone has a tip for me to make this code much cleaner.
Thanks!
P.S The comments are German, because I am german. Sorry
extends CharacterBody2D
const SPEED = 200
const JUMP_FORCE = -40
var gravity = ProjectSettings.get_setting("physics/2d/default_gravity")
var canceableAnimation = false
@onready var anim = $AnimationPlayer
enum PlayerState { # Diese Enumeration möchte Ich zum besseren wechseln des Statuses des Spielers benutzen.
IDLE, # Für jeden Status gibt es ein Objekt in der enum. In der späteren Logik werden die Staten
RUNNING, # durchgewechselt, damit manche Aktionen unter gewissen Staten nicht druchgeführt werden
JUMPING, # können.
ATTACKING,
ATTACKING_BIG,
HEALING,
TAKING_DAMAGE,
DODGING
}
# currentPlayerState ist vom Datentyp PlayerState. Damit auch nur die Staten aus der enum in der Variable stehen können
var currentPlayerState: PlayerState = PlayerState.IDLE
func is_callable_state(state: PlayerState) -> bool:
return state in [PlayerState.ATTACKING, PlayerState.ATTACKING_BIG, PlayerState.HEALING, PlayerState.TAKING_DAMAGE, PlayerState.DODGING]
func canChangeState(ToState: PlayerState) -> bool: # Diese FUnktion prüft ob der Status geändert werden darf
match currentPlayerState:
PlayerState.IDLE:
# Vom IDLE State kann man nur in folgende States wechseln:
return ToState in [PlayerState.IDLE, PlayerState.RUNNING, PlayerState.JUMPING, PlayerState.ATTACKING, PlayerState.HEALING, PlayerState.TAKING_DAMAGE]
PlayerState.RUNNING:
# Vom Running State kann man nur in folgende States wechseln:
return ToState in [PlayerState.IDLE, PlayerState.RUNNING, PlayerState.JUMPING, PlayerState.ATTACKING, PlayerState.HEALING, PlayerState.TAKING_DAMAGE, PlayerState.DODGING]
PlayerState.JUMPING, PlayerState.ATTACKING, PlayerState.ATTACKING_BIG, PlayerState.HEALING, PlayerState.TAKING_DAMAGE:
# Bei diesen States darf der Status nicht geändert werden.
return false
PlayerState.DODGING:
# Nach dem Dodge sollen die States von IDLE oder RUN verfügbar sein
return ToState in [PlayerState.IDLE, PlayerState.RUNNING]
# Standartmäßig dürfen diese Übergänge garnicht ausgeführt werden, daher hier false returnen
return false
func setState(newState: PlayerState): # Diese Funktion setzt einen neuen Status, wenn er geändert werden darf
if is_callable_state(currentPlayerState) and currentPlayerState != newState:
print("Anim läuft noch, Zustand nicht abbrechbar: ", currentPlayerState)
return
if canChangeState(newState):
currentPlayerState = newState
print("Zustandgewechselt --> ", currentPlayerState)
updateAnimation(currentPlayerState)
else:
print("Zustand konnte nicht gewechselt werden: ", currentPlayerState, "--> ", newState)
func updateAnimation(state : PlayerState): # Diese Funktion aktualisiert die Animationen je nach Status
match state:
# 'passes' durch die jeweilige Animation ersetzen
PlayerState.IDLE:
anim.play("Player-Idle")
PlayerState.RUNNING:
anim.play("Player-Run")
PlayerState.JUMPING:
anim.play("Player-Jump")
PlayerState.ATTACKING:
anim.play("Player-Attack")
PlayerState.ATTACKING_BIG:
anim.play("Player-Attack-Big")
PlayerState.HEALING:
anim.play("Player-Healing")
PlayerState.TAKING_DAMAGE:
anim.play("Player-Hurt")
PlayerState.DODGING:
anim.play("Player-Dodge")
func _on_animation_player_animation_finished(_anim_name: StringName) -> void:
# Die Liste enthält die Zustände die nicht mit Animationsende beendet werden sollen
if currentPlayerState not in [PlayerState.IDLE, PlayerState.RUNNING, PlayerState.JUMPING]:
print("Anim beendet, Zustand auf IDLE gesetzt: ", currentPlayerState)
currentPlayerState = PlayerState.IDLE
updateAnimation(currentPlayerState)
func _ready():
anim.active = true
func _physics_process(delta: float) -> void:
inputHandle()
applyMovement(delta)
func inputHandle(): # Verändert die States je nach Player Eingabe
var direction = Input.get_axis("move-left", "move-right")
if direction != 0 and canChangeState(PlayerState.RUNNING):
setState(PlayerState.RUNNING)
if Input.is_action_just_pressed("move-jump") and canChangeState(PlayerState.JUMPING):
setState(PlayerState.JUMPING)
if Input.is_action_just_pressed("action-attack") and canChangeState(PlayerState.ATTACKING):
setState(PlayerState.ATTACKING)
if Input.is_action_just_pressed("action-attack-big") and canChangeState(PlayerState.ATTACKING_BIG):
print("dicker angriff")
setState(PlayerState.ATTACKING_BIG)
if Input.is_action_just_pressed("move-dodge") and canChangeState(PlayerState.DODGING):
setState(PlayerState.DODGING)
if Input.is_action_just_pressed("action-heal") and canChangeState(PlayerState.HEALING):
setState(PlayerState.HEALING)
func applyMovement(delta): # Wendet das Movement auf den CharacterBody an
# direction kann entweder -1 | 0 | 1
var direction = Input.get_axis("move-left", "move-right")
match currentPlayerState:
PlayerState.IDLE:
velocity.x = 0
PlayerState.RUNNING:
if direction:
velocity.x = direction * SPEED
else:
velocity.x = move_toward(velocity.x, 0, SPEED)
if velocity.x == 0:
setState(PlayerState.IDLE)
if direction < 0:
$AnimatedSprite2D.flip_h = true
$"DamageBox-Small"/CollisionShape2D.position.x = -23
$HitBox.position.x = -1
elif direction > 0:
$AnimatedSprite2D.flip_h = false
$"DamageBox-Small"/CollisionShape2D.position.x = 23
$HitBox.position.x = 1
PlayerState.JUMPING:
if is_on_floor():
velocity.y = JUMP_FORCE
PlayerState.DODGING:
velocity.x = direction * SPEED * 1.5
PlayerState.ATTACKING, PlayerState.ATTACKING_BIG, PlayerState.HEALING, PlayerState.TAKING_DAMAGE:
velocity.x = 0
velocity.y += gravity * delta
if is_on_floor() and currentPlayerState == PlayerState.JUMPING:
velocity.y = 0
currentPlayerState = PlayerState.IDLE
move_and_slide()