0 votes

Hello. I am making a top down shooter game. The character should rotate towards the mouse global position. Something like this:
Character rotating

As you can see, the character changes their sprite and the gun changes its rotation according to where the mouse is pointing at. Also, if the mouse is pointing down, the gun shows in front of the player. As you can see in the GIF below:
Character with gun in front

As I have seen. The character uses 4 different sprites (one looking at the front, at the front right, the right, back right and back), and then it flips the sprite according to the mouse.
The gun could be a separate sprite that does rotate looking to the mouse.
I have tried all of this, however, it looks pretty weird, and the direction detection tends to fail sometimes and the code is too messy. What would you recommend me to achieve this in the best way? Thanks.

PS: The game in the gifs above is "Enter the Gungeon"

in Engine by (97 points)

1 Answer

0 votes

idle is the idle animation of a sprite
runf is the run forward animation of a sprite
runb is the run backward animation of a sprite
sprMinipistol is the gun sprite.

var MAX_SPEED = 100
var motion = Vector2.ZERO
var target = Vector2()

func control(delta):
    target = get_global_mouse_position()
    if target.x > self.position.x :
    elif target.x < self.position.x :
    if target.y > self.position.y :
        get_node("sprMinipistol").z_index = 0
    else :
        get_node("sprMinipistol").z_index = -1
    if Input.is_action_just_pressed("click"):

onready var sprite = get_node("sprPlayer")
var anim = "idle"

func _physics_process(delta):
    target = get_global_mouse_position()
    if motion.x == 0:
        anim = "idle"
        anim = "runf"
    if target.x > self.position.x :
        if Input.is_action_pressed("ui_left") == true or Input.is_action_pressed("ui_down") == true:
            anim = "runb"
        elif Input.is_action_pressed("ui_right") == true or Input.is_action_pressed("ui_up") == true:
            anim = "runf" 
    elif target.x < self.position.x :
        if Input.is_action_pressed("ui_left") == true or Input.is_action_pressed("ui_up") == true:
            anim = "runf" 
        elif Input.is_action_pressed("ui_right") == true or Input.is_action_pressed("ui_down") == true:
            anim = "runb"
    var axis = get_input_axis()
    if axis == Vector2.ZERO:
        apply_friction(ACCELERATION * delta)
        apply_movement(axis * ACCELERATION * delta)
    motion = move_and_slide(motion)

func get_input_axis():
    var axis = Vector2.ZERO
    axis.x = int(Input.is_action_pressed("ui_right")) - int(Input.is_action_pressed("ui_left"))
    axis.y = int(Input.is_action_pressed("ui_down")) - int(Input.is_action_pressed("ui_up"))
    return axis.normalized()

func apply_friction(amount):
    if motion.length() > amount:
        motion -= motion.normalized() * amount
        motion = Vector2.ZERO

func apply_movement(acceleration):
    motion += acceleration
    motion = motion.clamped(MAX_SPEED)
by (58 points)

Use Animated sprites node to add Animated sprites

Is control(delta) called in _process?

You can call it under fucn _physics_process(delta) aswell

Welcome to Godot Engine Q&A, where you can ask questions and receive answers from other members of the community.

Please make sure to read How to use this Q&A? before posting your first questions.
Social login is currently unavailable. If you've previously logged in with a Facebook or GitHub account, use the I forgot my password link in the login box to set a password for your account. If you still can't access your account, send an email to webmaster@godotengine.org with your username.