This site is currently in read-only mode during migration to a new platform.
You cannot post questions, answers or comments, as they would be lost during the migration otherwise.
0 votes

I press the attack key and the animation doesn't last even 1 second

extends KinematicBody2D

const gravity = 500
const speed = 80
const jump_force = -250

var velocity = Vector2()
var movedirection = 0
var jump = false
var pre
fire = preload("res://Scenes/Fire.tscn")

func _physics_process(delta):

if Input.is_action_pressed("ui_right"):
    move_direction = 1
    $AnimatedSprite.flip_h = false
    $AnimatedSprite.play("running")

elif Input.is_action_pressed("ui_left"):
    move_direction = -1
    $AnimatedSprite.flip_h = true
    $AnimatedSprite.play("running")

else:
    move_direction = 0
    $AnimatedSprite.play("idle")

if is_on_floor():
    if Input.is_action_pressed("ui_space"):
        jump = true
    else:
        velocity.y = 0
else:
    $AnimatedSprite.play("jump")

if jump:
    velocity.y = jump_force
    jump = false

velocity.y += gravity * delta
velocity.x = speed * move_direction

if Input.is_action_just_pressed("ui_shoot"):
    var fire = pre_fire.instance()
    fire.global_position = $boca.global_position
    get_parent().add_child(fire)
    $AnimatedSprite.play("atack")

move_and_slide(velocity, Vector2(0, -1))
in Engine by (21 points)

1 Answer

+3 votes
Best answer

you are overriding the animation with your movements and idle.

do you want to be still in your animations? do you want to cancel them by moving/jumping only?

for the first one you can make a check before each call to animation player as such:

if $AnimationPlayer.current_animation == "atack" and $AnimationPlayer.is_playing():
    pass
else:
    $AnimationPlayer.play("walk")
    #tie your move actions to this condition as well.

this is assuming your shot animation is not looped.

in the case you want to cancel it by moving and jumping, but not idle, you can just add this before the idle animation

if $AnimationPlayer.current_animation == "atack" and $AnimationPlayer.is_playing():
    pass
else:
    $AnimationPlayer.play("idle")
by (53 points)
selected by

I am not using Animation Player, I am using Animated Sprite, and it is not working with Animated Sprite, when I put it gives an error

Sorry for misreading.

you have in animated sprite an attribute called "animation" and a method called "is_playing".
you should be able to replace "current_animation" with the "animation" attribute and try it again.

also, can you post the error given by the engine?

This is the error Invalid get index 'current_animation' (on base: 'AnimatedSprite').

Where i can find this attribute?

so. in the type of programing godot uses you have things called Objects. objects have attributes and methods.

attributes are variables belonging to that object. methods are functions of the object.

when you create AnimatedSprite you create an instance of that object.

to access attributes, you can use $AnimatedSprite.attribute

to access methods you can use $AnimatedSprite.method() for example.

you can see which attributes and method an object has if you go to the documentation page for it. attributes will be at the top and then you will see all the methods available.

the error you got was trying to get an attribute that AnimatedSprite didn't have.
to solve this you can get its attribute of current animation, "animation" or
$AnimatedSprite.animation

I put like this:
if $AnimatedSprite.attribute("atack") and $AnimatedSprite.method.is_playing():

And gives another error: Invalid call. Nonexistent function 'attribute' in base 'AnimtedSprite'.

the right way to use attributes and methods is with their name, without their type before.
methods are only visibly different by having parentheses

for example, in your code it would look like this:

 if $AnimatedSprite.animation == "atack" and $AnimatedSprite.is_playing():

do notice that the is_playing() method returns a true/false value, so no tests are needed on it.

when you have an object in your scene, you can usually get its node and start typing "." and see what attributes and features it shows you.

It was like this:

extends KinematicBody2D

const gravity = 500
const speed = 80
const jump_force = -250

var velocity = Vector2()
var movedirection = 0
var jump = false
var pre
fire = preload("res://Scenes/Fire.tscn")

func physicsprocess(delta):

if Input.is_action_pressed("ui_right"):
    move_direction = 1
    $AnimatedSprite.flip_h = false
    $AnimatedSprite.play("correndo")

elif Input.is_action_pressed("ui_left"):
    move_direction = -1
    $AnimatedSprite.flip_h = true
    $AnimatedSprite.play("correndo")

if $AnimatedSprite.animation == "atacando" and $AnimatedSprite.is_playing():

    pass

else:
    move_direction = 0
    $AnimatedSprite.play("parado")

if is_on_floor():
    if Input.is_action_pressed("ui_space"):
        jump = true
    else:
        velocity.y = 0
else:
    $AnimatedSprite.play("pulando")

if jump:
    velocity.y = jump_force
    jump = false

velocity.y += gravity * delta
velocity.x = speed * move_direction

if Input.is_action_just_pressed("ui_shoot"):
    if get_tree().get_nodes_in_group("fire_balls").size() < 1:
        var fire = pre_fire.instance()
        fire.global_position = $boca.global_position
        get_parent().add_child(fire)
        $AnimatedSprite.play("atacando")

move_and_slide(velocity, Vector2(0, -1))

But now the character doesn't move and the animation keeps stopping

alright. i tested your code. my version of it now works as intended.

first, add a idle frame to the fire animation at the end. lets say that frame's number is N.
this frame signals that the animation finished. you can just replicate the last frame instead.

now you can use the test:

if $AnimatedSprite.animation == "attack" and $AnimatedSprite.frame != N:
  pass
else:
  move_direction =0 
  $AnimatedSprite.play("idle")

the other thing that caused you being stuck in place is that this if statement needs to be on the end of the movement loop.

so the correct loop would be:

if Input.is_action_pressed("ui_right"):
    move_direction = 1
    $AnimatedSprite.flip_h = false
    $AnimatedSprite.play("running")
elif Input.is_action_pressed("ui_left"):
    move_direction = -1
    $AnimatedSprite.flip_h = true
    $AnimatedSprite.play("running")
else:
    if $AnimatedSprite.animation == "attack" and $AnimatedSprite.frame != N:
        pass
    else:
        move_direction = 0 
        $AnimatedSprite.play("idle")

hope this helps.

Thank you bro!!!!!

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 Frequently asked questions and 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 [email protected] with your username.