Godot Version
4.6.1.stable
Question
My 2D topdown character doesn’t flip sometimes, please, fix it, I wish the flip of the character would work every time by pressing left or right button.
extends CharacterBody2D
@export var speed: float = 500.0
@export var body_part: Array[Node]
@export var bullet_prefab: PackedScene
@export var shoot_delay: float = 0.05
@export var gun_rotation_offset: float = 0.0
@export var mouse_sensitivity: float = 0.03
@export var invert_mouse: bool = false
@export var rotation_smooth: float = 0.2
@onready var anim: AnimationPlayer = %anim
@onready var gun: Node2D = %Pistol
@onready var bullet_start_pos: Node2D = %bullet_start_pos
var _anim_i: Array[int] = [0, 0]
var _device: int = 0
var save_system: Node
var SFX: Node
var game_ui: Node
var fire_timer: float = 0.0
var mouse_delta: Vector2 = Vector2.ZERO
var is_facing_right: bool = false
func _init() -> void:
add_to_group("player")
add_to_group("player" + str(_device))
func _ready() -> void:
save_system = Global.find_node_in_group("save_system")
SFX = Global.find_node_in_group("SFX")
game_ui = Global.find_node_in_group("game_ui")
load_cutstom()
func load_cutstom() -> void:
if save_system:
save_system.load_gslot()
_anim_i[0] = save_system.gslot["idle"]
_anim_i[1] = save_system.gslot["walk"]
load_all_body()
func load_all_body() -> void:
for i: int in body_part.size():
var saved_body_part: int = save_system.gslot["body_part"][i]
replace_body_part(body_part[i], saved_body_part)
load_color(i)
func replace_body_part(_n: Sprite2D, saved: int) -> void:
saved = clamp(saved, 0, 2)
var cat_id: int = saved + 1
var part_name: String = _n.name.to_lower()
var path: String = "res://Image/Game/Player/Cat_%d/Cat_%d_%s.png" % [cat_id, cat_id, part_name]
var tex: Texture = load(path)
if tex:
_n.texture = tex
func load_color(_i: int) -> void:
var v: String = save_system.gslot["body_color"][_i]
var _color: Color = Color(v)
body_part[_i].self_modulate = _color
func _input(event: InputEvent) -> void:
if event is InputEventMouseMotion and Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
mouse_delta += event.relative
func _physics_process(delta: float) -> void:
var input_dir: Vector2 = Vector2.ZERO
input_dir.x = Input.get_action_strength("right" + str(_device)) - Input.get_action_strength("left" + str(_device))
input_dir.y = Input.get_action_strength("down" + str(_device)) - Input.get_action_strength("up" + str(_device))
input_dir = input_dir.normalized()
velocity = input_dir * speed
move_and_slide()
handle_animation(input_dir)
handle_flip(input_dir)
handle_aim(delta)
handle_shoot(delta)
func handle_animation(input_dir: Vector2) -> void:
if input_dir.length() > 0.0:
var anim_name: String = "walk" + str(_anim_i[1])
if anim.current_animation != anim_name:
anim.play(anim_name)
else:
var anim_name: String = "idle" + str(_anim_i[0])
if anim.current_animation != anim_name:
anim.play(anim_name)
func handle_flip(input_dir: Vector2) -> void:
if input_dir.x > 0.0:
if not is_facing_right:
scale.x = -1
is_facing_right = true
else:
if is_facing_right:
scale.x = 1
is_facing_right = false
func handle_aim(_delta: float) -> void:
var joy_x: float = Input.get_joy_axis(_device, JOY_AXIS_RIGHT_X)
var joy_y: float = Input.get_joy_axis(_device, JOY_AXIS_RIGHT_Y)
var stick: Vector2 = Vector2(joy_x, joy_y)
if stick.length() > 0.2:
var aim_dir: Vector2 = stick.normalized()
var target_angle: float = aim_dir.angle()
gun.rotation = lerp_angle(gun.rotation, target_angle, rotation_smooth)
else:
if Input.get_mouse_mode() == Input.MOUSE_MODE_CAPTURED:
var invert: float = (1.0 if invert_mouse else -1.0)
gun.rotation += mouse_delta.x * mouse_sensitivity * invert
mouse_delta = Vector2.ZERO
else:
var aim_pos: Vector2 = get_global_mouse_position()
gun.rotation = (aim_pos - gun.global_position).angle()
func handle_shoot(delta: float) -> void:
fire_timer -= delta
if fire_timer <= 0.0:
shoot()
fire_timer = shoot_delay
func shoot() -> void:
if not bullet_prefab:
return
var bullet: Node = bullet_prefab.instantiate()
get_parent().add_child(bullet)
bullet.global_position = bullet_start_pos.global_position
bullet.game_ui = game_ui
var dir: Vector2 = Vector2.LEFT.rotated(gun.rotation)
if is_facing_right:
dir.x *= -1
bullet.direction = dir.normalized()
bullet.rotation = dir.angle()
bullet.shooter = self
func damage() -> void:
if game_ui:
game_ui.damage()