Character Movement / Smoothness Issue + Other Question

Started by Tycho Magnetic Anomaly, Thu 15/06/2017 15:11:01

Previous topic - Next topic

Tycho Magnetic Anomaly

Hi folks I got a little time over the last day to try a few experiments with ags to see what it can do/ if its viable for a project idea.

Right now i am testing how ags dose movement and I was hoping to ask a few questions related to it.

My test involved a box(char) that moves from point a to point b in a test scene that is set to be 60fps. and my question here is it possible for this movement to have acceleration / deceleration curves to when the box start to move it will gradually speed up to a defined speed, then at the end of its move gradually slow down...  in effect i am asking is it possible to do ease in / ease out with ags.

During my test I also note that when the char moves from point a to b it looks really jerky as if its in a very low fps, yet the game settings are set to run at 60fps.

I understand that the Tween module can achieve some sort of ease/in/out but apparently (From my research) that it ignores walk-able areas.

Also slightly unrelated question .. but
Is it possible for ags (or the tween module ) to cross-fade between 2 images over a given length of time. If not cross-fade between two image can it at least fade in an image over some other image.


Snarky

Quote from: Tycho Magnetic Anomaly on Thu 15/06/2017 15:11:01
During my test I also note that when the char moves from point a to b it looks really jerky as if its in a very low fps, yet the game settings are set to run at 60fps.

This is probably because of your character's MovementSpeed and AnimationDelay/Speed. If the AnimationDelay is set to 4, for example, your 60 fps will be cut to 15 fps.

Quotein effect i am asking is it possible to do ease in / ease out with ags.

I understand that the Tween module can achieve some sort of ease/in/out but apparently (From my research) that it ignores walk-able areas.

Yes, use the Tween module, and yes, it ignores walkable areas. If you want it to move along a non-direct path from Point A to Point B, you can simply do that directly in code, though if you want to accelerate while changing the trajectory it gets a bit tricky. At that point you might just have to write your own movement equation. (It's not actually all that hard.)

QuoteIs it possible for ags (or the tween module ) to cross-fade between 2 images over a given length of time. If not cross-fade between two image can it at least fade in an image over some other image.

You can't crossfade images exactly, but you can fade on image on top of another, which for almost all intents and purposes amounts to the same thing (the exception is if they have alpha transparency, as I don't think there's a way to get AGS to linearly interpolate the alpha masks from one image to another) â€" there is a hack that would allow you to crossfade if you set the game to use old-style alpha blending (because AGS used to use an incorrect alpha calculation that you can exploit), but I wouldn't recommend it. I once used it to do sub-pixel positioning back in the day.

Tycho Magnetic Anomaly

#2
Thank you so much for the advice snarky... ah its good about the image fade in at least, that should suffice.

Ok regarding the movement, I have a particular setup that is confusing me a bit. I do "think" I understand about how ags moves a character, and how that also related to tweening..etc

Ok so my situation is this, lets assume my box has a really rapidly flashing light.. almost like a strobe, and this strobe has to stay at the same rate while the character is moving. So lets assume the light flashing is a 3 frame animation on the sprite and its rate is 33ms ... is it then possible to combine a 60fps smooth movement while not interfering with the rate of the animation?

And on top of that is it then possible to achieve ease in / ease out on the movement also?  or is all 3 aspects of this asking a bit too much of ags? sorry learning the limitations of ags atm

Snarky

AGS offers a few different ways to move things around on the screen:

-Walk (only for Characters): this normally links movement to an animation (the walkcycle). The animation will only play while the character is walking, and the character will (usually) only move when the animation frame changes. The character will automatically switch animation to face in the right direction. The path is normally constrained by walkable areas. The speed is usually constant throughout the movement, (but normally affected by scaling).

-Move (Characters and Objects): this allows you to move characters and objects around without the movement being linked to an animation. Because it's not linked to animation, the character/object moves every game loop for smoother movement. I'm not sure whether characters turn around to face in the direction they're moving, but objects certainly don't. Similarly, this command won't play any animation, but you can do so with another command, independently. Path can be constrained by walkable areas or not, as you choose. The speed is usually constant throughout the movement.

-Setting the X and Y coordinates directly (Characters and Objects, as well as GUIs and other things): this is how the Tween module works, or you can write your own code to do it. Using the Tween module, you can vary the movement speed during the move (ease in/out), but the path will not be constrained by walkable areas. (A straight path is easiest, but you can also create other curves by tweening X and Y separately with different tweening functions.) Setting X/Y coordinates doesn't play any animation, but again, you can simply animate it yourself. It does not affect the direction characters face.


Your first step should therefore be to figure out if your blinking box needs to be a character:

-As it moves, does it turn around so you see it from different angles?
-Does it move between different rooms?

If the answer is no to both, it might just as well be an object.

If you do want it to face in different directions, your problem is a little tricky (because the easiest way to do that is with Walk, but it doesn't let you do easing). If not, You should simply Animate it separately, and use most likely the Tween function to move it around on the screen.

Tycho Magnetic Anomaly

Thank you once again snarky...  Managed to get the box at lest moving smooth in relation to the test's 60fps. also managed to get the strobe at a consistent rate with that movement.

I will look into your other pieces of advice..  I think I am homing in on some compromise at least

(also yes in this case its a char that turns (front,back & Side+mirrored) so 4 directions.

Nikujaga

Quite have the opposite question here  :grin: trying to understand how to mimic AGS character walk in Godot in order to make it less smooth.

I am new to game development / programming and am trying out both AGS and Godot. I would like to know how character walk works exactly in AGS:

Quote-Walk (only for Characters): this normally links movement to an animation (the walkcycle). The animation will only play while the character is walking, and the character will (usually) only move when the animation frame changes. The character will automatically switch animation to face in the right direction. The path is normally constrained by walkable areas. The speed is usually constant throughout the movement, (but normally affected by scaling).

Is it possible how exactly are movement and animation linked ? I mean if movement happens everytime the sprite changes, by how many pixels is it put forward ?

I am trying to replicate AGS's Tumbleweed template with Godot and so far my character looks like sliding on the floor with Godot (see here ; don't mind about the lagging, capture software is responsible of it; more generally look at any video of Pizza Boy and Dog Mendonça and you will see characters definitely look like sliding on the floor).
I think this is because the function I am using (Navigation2D.get_simple_path() for those of you who know about Godot) implies a continuous translation of the object Character. So the opposite of how I understand AGS works.

Khris

AGS moves the sprite x amount of pixels every y frames.
x must be based on the sprites, meaning it must be exactly equal to the amount of pixels a foot on the ground moves back in the walkcycle, to prevent moonwalking / gliding.
y on the other hand determines the speed of the animation and therefore of the character.
How exactly does Godot move the character? Do you have control over the position in pixels?

Nikujaga

Ok so if I understand well, in AGS, the Character "MovementSpeed" property sets by how many pixels the character should move (this amount of pixels needs to be specific to the sprite itself in order to avoid a glidin effect), and when "MovementLinkedToAnimation" == True this movement is not indexed on real time directly nor on frames but on changes of sprites ( "each time the loop's sprite changes, advance X pixels"), which means it is indexed on "AnimationDelay".

AnimationDelay counts frames, am I right ? But then how can I check how many frames per second AGS processes ?

I'd tend to say there are ways to have control over position in pixel with Godot  ; but as a complete beginner my problem is about knowing how to do it  :grin:

So far I have found 3+1 properties that impact character movement in Godot :

  • Speed : which is used in order to set by how many pixels the object moves per frame
  • Animation Speed (FPS) : which sets how many sprites are played per second
  • Speed Scale : which multiplies Animation Speed

The 4th parameter is line 13 of my code ("direction" is a vector of lenght 1) :

Code: Godot
# How much distance can the player cover in one frame
	var distance_per_frame = speed * delta
	
	# This loop moves the player along the path until he has run out of movement
			# or the path ends
	while distance_per_frame > 0 and path.size() > 0:
		var distance_to_next_point = position.distance_to(path[0])
		if distance_per_frame <= distance_to_next_point:
			# If the player cannot cover distance_to_next_point distance in
					# one frame then its position is incremented by 
					# distance_per_frame in the path direction
			direction = position.direction_to(path[0])
			position += direction * distance_per_frame
		else:
			# The player gets to the next point
			position = path[0]
			path.remove(0)
		# Update the distance to walk
		distance_per_frame -= distance_to_next_point
		if path.empty() == true:
			direction = Vector2.ZERO


I tried the following :

  • Godot.Speed = AGS.MovementSpeed = 4
  • Godot.AnimationSpeed = AGS.AnimationDelay = 4
  • Godot.SpeedScale = 1

But it doesn't work, and I think it is because Godot.AnimationSpeed calculates how many sprites should be played per second, whereas AGS.AnimationDelay counts how many frames should a sprite last before changing.
So obviously these two can't be equal... I am very bad at math, do you have an idea of how these two parameters could be related ?
[/list]

Khris

AGS runs at 40 FPS by default, so an AnimationDelay of 4 means 40/4 = 10 frame changes per second.

Snarky


Khris

Right; 4 probably means 40/(4+1) = 8 frame changes per second.

Nikujaga

Thank you for your replies.

AnimationDelay = 0 makes the animation run much faster, I guess the animation sprite is updated at the engine framerate ?


The more I think about all this the more I end un believing that the whole thing relies in the "MovementLinekdToAnimation" parameter. Setting it on TRUE is logically the ONLY way to make movement happen on a discrete basis, not continuous.
How does this parameter work ? I mean how is it coded ?

Khris

Say you have an AnimationDelay of 3, and a MovementSpeed of 5.
This means the character's sprite will change every 4 frames (at a default game speed of 40FPS, a frame lasts for 0.1 seconds)

If MovementLinkedToAnimation is true, the character is also only moved every 4 frames, at the same time the sprite changes. Which means walking 100 pixels will take them 2 seconds, since the character needs 100/5 = 20 frame changes, 20 * 0.1 = 2

If MovementLinkedToAnimation is false, the character is moved every frame. Which means walking 100 pixels will take them 0.5 seconds, since the character needs 100/5 = 20 frame changes, 20 / 40 = 0.5

If you have a character that touches the ground, to avoid moonwalking/gliding, you need to turn it on, and set MovementSpeed to the pixel value determined by the animation frames. Then you adjust the speed via AnimationDelay.

For a character that's hovering or flying or whatever, you can turn it off, and adjust both values independently.

Danvzare

#13
Quote from: Khris on Thu 21/05/2020 10:09:15
If you have a character that touches the ground, to avoid moonwalking/gliding, you need to turn it on
In my experience, if you're getting gliding with it off, you either need more animation frames or have the animation play a lot quicker.
If you do it right, it gives a very smooth look that I very much prefer to the almost sickening jumpiness most games get when it's on.  :-X

But Nikujaga doesn't want smoothness.
In which case MovementLinkedToAnimation should definitely be on. And you'll want AnimationDelay to be higher than 0, so the jumps between frames seem sporadic. You'll also want AnimationSpeed to be at a pretty high value, so that you can get some really jarring leaps (it'll make you feel nauseous if the room is a scrolling room, but if that's what you want).
Just experiment with high and low values between them until you get something similar to what you want.
But that's just how it works in AGS. How to mimic it in Godot should be as simple as having the sprite only move when its frame changes (based on AnimationDelay) and having it move a specific amount of pixels (based on AnimationSpeed). At least, that's my two cents.

Snarky

If you don't want it to glide with MovementLinkedToAnimation off, you'll need one animation frame for each game loop. At standard game speed, that's 40 frames per second.

Benjiman33

I have a similar issue with a lack of smoothness with AGS.
I made a short video (Unity first then AGS) : https://www.youtube.com/watch?v=YmdaguJFz10 - The movement is a lot more fluid with Unity (it's not that visible on the video)

I'm working with MovementLinkedToanimation = False and a slow animationDelay (=2)
With the same sprites i'm not able to reproduce the smoothness from unity... Am i missing something ?

Crimson Wizard

^ It's hard to tell for certain without analysing closely what's going on in both games, but first thought that comes to mind, Unity uses floats for internal coordinates, while AGS uses integers.
It may be possible to script custom movement using floats in AGS too, but engine currently does not expose pathfinding into scripting API, so that may be far from trivial.

Cassiebsg

To  be fair they both like their sliding. Feels like there's one of his foot that never leaves the ground, so it slides instead of producing impulse.  :-\
There are those who believe that life here began out there...

Benjiman33

Yeah @Cassiebsg i know i have an issue with the walk cycle ^^ but my point was more about the "blurry" effect for the movement. It happens even if u look only the head.
Thanks for your answer Crimson, i will make more tests and I let you know if I find something more blatant

morganw

Are you sure it isn't just that you are scaling the game to fit the window size?

SMF spam blocked by CleanTalk