Jump to content

Need help with smooth movement animation in tile snake game


Recommended Posts

Hey guys, 

Sorry if it is trivial stuff, but I have not found any solution to this issue anywhere.


What I have:

I have a snake grid-based game with enemies which could move as well. Snake speed can vary and it could move faster or slower, as well as the enemies speed.

The animation is independent of the rest of the game, so I just move snake and enemies every N ms one tile and then redraw their positions.


What is the issue:

This animation does not provide smooth snake movement, because it moves by tiles (120px) and I am struggling to make a smooth snake and enemies movement. 


What have I tried:

I tried to move enemy and snake every 30 frames and then make a tween animation with 30 frames delay to the destination enemy/snake x/y coordinates. When the snake moved faster, I waited 20 frames. 

This solution is really ugly and if frames drop occurs, the whole game starts to freeze. Also, different fps provide different game speed.


Please advise me how I can achieve the smooth movement, I want to have the animation independent of the main game loop which moves everything by tiles, and I want to have the ability to increase/decrease the speed of snake and enemies. Thanks!

Link to comment
Share on other sites

Yeah, you don't want to tie so completely to frame rate (actually this isn't strictly true, you might want to be frame rate based, then you don't have to deal with interpolation and so makes things simpler. Usually you would want to deal with it though).

You usually want to interpolate based on the current frame rate, or time elapsed since last iteration, which is pretty much the same thing.

i.e. (I've picked some numbers to make the maths easier to follow)

* Move from [0, 0] to [10,0]. Move takes 1000ms. This move has a distance of 10 units (not pixels, do not use pixels, they make no sense here as a distance unit).

* Next tick is 200ms later, so we need to move 20% of the distance units,  i.e. 200 / 1000 * 10 = 2 units. So move to [2, 0].

* Lets say next tick is 400ms later. 400 / 1000 * 10 = 4. So move to [6, 0].

* Repeat until move is complete.

In a real world example you'll end up with lots of decimals like attempting to move to [0.4, 0] for example. This is why we don't use pixels to represent distance. Your renderer should map position [0.4, 0] into whatever pixel position represents that on the screen. Depending on your resolution things like moving from [0.4, 0] to [0.6, 0] might mean your snake does not actually move on screen, but it moves in your world simulation.

This can all be done in a euclidean tile map, and if you only have 4 (or even 8 with diagonals) directions that might be easier.

Using a vector based system makes some of this easier in some ways, but is more beneficial when you can move in any direction, still might be useful.

i.e an entity has a speed, a direction and a position, each tick you apply speed * direction to position to get your movement. To decouple this from frame-rate you'd still need to do the interpolation as well which gives you how _much_ you have moved this tick, I'm going from memory but I think it is applying speed * direction * interpolation to position.

Link to comment
Share on other sites

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.
Note: Your post will require moderator approval before it will be visible.

Reply to this topic...

×   Pasted as rich text.   Paste as plain text instead

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.


  • Recently Browsing   0 members

    • No registered users viewing this page.
  • Create New...