Was making a pong game and I implemented the enemy AI but when he moves, the animation only plays the first frame each frame so it looks like it is stuttering, I am sure that's because it is checking the position each frame and changing the movement vector each frame so it looks like as if it is pressing the button each frame instead of holding it down because of the delta time, but I don't know how to fix it, please help it is stressing me out lol
#Need help with my pong game
144 messages · Page 1 of 1 (latest)
@export var speed = 600
var hit : bool
@onready var movement = Vector2.ZERO
func _physics_process(delta):
movement = Vector2.ZERO
if GlobalVariables.scored == false and GlobalVariables.start == false:
if abs($"../Ball".position.y - position.y) > 25:
if $"../Ball".position.y > position.y:
movement = Vector2.DOWN
elif $"../Ball".position.y < position.y:
movement = Vector2.UP
if GlobalVariables.scored == false and GlobalVariables.start == false and movement == Vector2.ZERO:
$"RA".play("Idle")
if not movement == Vector2.ZERO:
$"RA".play("Run")
if $Timer.time_left <= 0:
$Walking.pitch_scale = randf_range(0.8, 1.02)
$Walking.play()
$Timer.start(0.250)
if hit == true:
$"RA".play("Hit")
move_and_collide(movement * delta * speed)
func _on_area_2d_area_entered(area):
hit = true
await get_tree().create_timer(0.1).timeout
hit = false```
...anyone?
Maybe you need to ensure that the run animation isn't already playing, because if you start playing it each frame it'll reset to the first frame
if RA.current_animation != "Run" or something
i didnt mean to make it play each frame
i will try that in a lil bit one second
there is no .current_animation variable
nope, doesnt work
any other ideas?
i feel like i need to put the function that triggers the run animation OUTSIDE of the delta function
but idk where else to put it
make it play once?
Yeah that's the idea
It has to loop as long as velocity isn't zero
But checks its position relative to the balls position each frame
And moves it
So it is as if it is spamming the movement button extremely fast, instead of holding it down
Code and issue is up there I am really stumped
That's the last hurdle I gotta pass
I think the issue is not with your animation but the enemy's movement. You are checking if the enemy is more than 25 pixels above or below the ball and then moving them in the appropriate direction up or down. But the enemy is moving so fast it is catching up with the ball, so it is nolonger outside the 25 pixel boundary, which makes it stop moving and go into the idle animation. The ball carrys on moving until the enemy is outside the 25 pixel boundary again and so the enemy starts moving with the walk animation and so on. That is what is making the animation stutter, the enemy is repeatedly switching between walk and idle states.
One way to fix this would be to make the enemy follow the ball at the same speed the ball is moving. Try replacing:
if abs($"../Ball".position.y - position.y) > 25:
if $"../Ball".position.y > position.y:
movement = Vector2.DOWN
elif $"../Ball".position.y < position.y:
movement = Vector2.UP
With:
if abs($"../Ball".position.y - position.y) > 25:
movement = $"../Ball".velocity.y
I can't do that, then it would always just win
And the ball is gradually getting faster
What if I just remove the 25 pixels requirement?
Why do you use an animation to move your enemy? Why not set the position of the paddle just via code?
ah i could try helping but i only mess with c#, only if you acept c# solutions aswell
Try it without the 25 pixel requirement but I think that might lead to the enemies jittering because they would keep overshooting the exact position of the ball.
Instead you could limit the enemy's movement speed with:
if abs($"../Ball".position.y - position.y) > 25:
movement = $"../Ball".velocity.y.limit_length(max_speed)
And having max_speed set to the maximum speed you want the enemy to be able to move at.
if hit = true then $"RA".play("Hit"), is this correct? like that, let's suppose the hit bool stays on for 4 miliseconds, if that's so then the "Hit" animation will play on these 4 times that the frame repeat, i had some troubles with that on the past, instead of checking the position and doing so the timer waits 0.1 frames, you could just assign the animation to play when the area is triggered
func _on_area_2d_area_entered(area):
$"RA".play("Hit")
like this, you will not be on the need of creating a bool to check if it got collided
if it's not that, i'm not sure because i used to unity and i'm kinda a newbie to godot lol, so i'm not sure how animation trees and stuff works properly on godot
Godot Engine documentation
Inherits: AnimationMixer< Node< Object A node used for animation playback. Description: An animation player is used for general-purpose playback of animations. It contains a dictionary of Animation...
...why would I?
Animated sprite 2d has .animation variable, didn't work
Yeah there is no issue with the hit animation
Thanks I will still use that but my issue is the run animation
oops, its an AnimatedSprite. i thought we were talking about AnimationPlayer
Godot Engine documentation
Inherits: Node2D< CanvasItem< Node< Object Sprite node that contains multiple textures as frames to play for animation. Description: AnimatedSprite2D is similar to the Sprite2D node, except it carr...
Is playing checks if an animation is playing
At all
Regardless of which animation
I will try this and let u guys know if it works
But I have to sleep for now
i havent worked with the animated sprite editor yet, but wouldnt you use some kind of loop in the run animation and not in any of the others?
that would mean
if not $"RA".is_playing():
$"RA".play("Run")
should let the hit animation finish and then start but never start again while running
Idle animation also has a loop
It just has a loop option you can turn on
When you set the animations themselves
Idle animation needs a loop too
So does the winning animation
And losing
Should still try it cuz
No animation would be playing while velocity is not zero
If I delete the line so it might work
ok then, here's another idea
on the animtation tree, replace the idle and walk animations for a blendTree instead
after that, add the idle and walk animations inside the blend tree, they both need to be set as loop
after that, calculate the velocity of the enemy Y position, and set the influence of the blend tree to the value of the Y velocity
an example of this is:
Vector2 corrected = new Vector2(velocity.X, velocity.Y);
anim.Set("parameters/idle/blend_position", corrected);
for example, if the velocity Y is 1 or -1 and you take the Absolute value of it, the blend position will be set to 1 which will be the walking animation, and if it's 0(not moving) the idle animation will be the one playing
using this you don't need to check if it is moving or it's stopped to use animTree.play all the time
on my example, my script takes the coordinates of the velocity X and Y and sets the influence(the blue crosshair) to the velocity
let's see if i can generate a godot code for that...
func _physics_process(delta: float) -> void:
var corrected = Vector2(velocity.x, velocity.y * -1)
anim.set("parameters/idle/blend_position", corrected * 1.0)
this should work, now, pay attention on "idle", "idle" is the animation of the animation tree
I wasn't using anim tree to begin with I will have to figure that out
Why do we correct vector2 tho?
I will try it if the first suggestion doesn't work
ohh nono
for my game, i needed the velocity.Y to be the opposite value so i did it *-1, but i don't think you'll need that
Oh alright
it is handy, i guess this i'll help you out https://docs.godotengine.org/en/stable/tutorials/animation/animation_tree.html
Godot Engine documentation
Introduction: With AnimationPlayer, Godot has one of the most flexible animation systems that you can find in any game engine. The ability to animate almost any property in any node or resource, as...
I will find a YouTube guide for it I can't learn from scratch with the docs
Learn how to move and animate a top down 2d sprite in Godot. I go over basic physics movement, AnimationPlayer, and AnimationTree.
Spritesheet: https://raw.githubusercontent.com/jontopielski/Top-Down-Sprite-Tutorial/master/player/PlayerSpriteSheet.png
Code: https://github.com/jontopielski/Top-Down-Sprite-Tutorial
00:00 - Intro
00:07 - Scene S...
i leant from this one when i was starting on godot
the sprite animation node is generally good for specific things, when you want to implement something complex like that, you'll need to mess with a lot of things to check if animations are overrided and stuff, it's very instable on some cases
on your case is really better to adopt the animation tree node

did it worked?
It is too late in the night I am too tired to get on laptop
I will try it in the morning!
i have another question
oh it was just the text allignment nvm
was gonna ask why one of my buttons have an effect when i hover and click but it was just that it was alligned to left instead of center, all good
but if i do that the enemy will also be getting gradually faster from the start
reducing the difference between them and making the ball a bit faster fixed it for some reason
as far as i can see
it is probably still janky but i will keep it for a first try
nevermind it is very jittery
i will try animation tree
i gotta merge all my spritesheets together to use animation tree..?
this isnt the same
some things in my animation tree isnt in the video, some things in the video isnt in mine
this is driving me crazy
Can you send a screenshot?
there is no button to make it start in that state and the start and end stuff arent in the video
i am getting a headache
it must be godot 3 the video is from 3 years ago
i will go find another way
Send the code again?
Click on the ->- button
And create a transition from start to Idle
Right click the start state and set it to the idle state
Oops, you coded it like it was still a sprite2D animation
Ok, enter to your Idle state, let's see what you put in there
already deleted animation tree was stressing me out
Uh oh
Do you mind If you sent the project to do it for you? Later on i give you a explanation
nah i will take a break
it stressed me out too much
Sorry for that
i made half of the field an area
and if the ball enters there run should play
but it doesnt
why doesnt it work
i think cuz on area entered it only triggers the frame it enters the area?
i just made the ball faster, it does look good
or least is fast enough to not be noticable
i also made it so that the enemy stops moving once the ball bounces off of him, and starts moving when it enters his half, so he cant catch up sometimes
i've sent a lot of messages in dm explaining the animationtree thingy, in case you wanna know about it later
Maybe later, I am tired of it rn, I will just finish the rest of this and call it a day
i have another problem, followed a guide and made a scene transition, put it on autoload, called it in the actual scene, but this is what happens
Howdy! Changing your scenes is important, otherwise your players will only ever play at most one level of your game. In this video, you'll learn how to implement an animated scene transition that is consistent throughout your game. You build this once and you can use it anywhere. Transition from the overworld to your level, level to overworld, o...
i followed this guide
i followed it word by work i dont know what i missed
anyone at all..?



