Advertisement

Snake game, configurable section distance

Started by June 08, 2020 11:42 AM
6 comments, last by SillyCow 4 years, 8 months ago

I want to make a snake game. In a classic game the snake moves in 4 directions. I want the player to move in all directions by mouse input, similar to slither.io

Right now the tail section changes its position after the head. I'm using an array, adding to the top the head position and removing the last element from the bottom. If I increase the speed, the sections move away from each other. How can I make the sections not move away from each other and have a configurable distance between them?

How do you increase speed?

You move the segments further, and you have fixed length segments?

Did you try drawing on paper how to move? That should give insight in how each segment changes each frame.

Advertisement

Not tried this, so it is more of a this is an approach I would try. Instead of storing positions, store line segments in an array that represent the path the worm has traveled. At update when you step the head to its next position, add line segment from the old position to the new position. Then draw the head at the start of the line. Move along the line a certain (configurable) distance and draw the next segment, actually you will probably want to start at the tail to get the draw order right if there are overlaps. You will need to know how to calculate position at distance along line (made up of the line segments).

Line segments can be removed once a segment is far enough away from the head that it's not needed for drawing.

The shorter version is: You control a line that your draw code will layout segments of a worm on. This is more complicated than the classic snake game, so there might be a simpler way?

Hope that helps/makes sense

//everything here is in vectors
moveSegment(){
 vector direction = next_segment_position - this_segment_position
 float gap = direction.length() - LENGTH_OF_SEGMENT 
 // has the next segment moved away?
 if(gap > 0){
    //close the gap
 	this_segment.position += normalize(direction) * gap 
 }
}

This method will cause the snake to move realistically (like a real snake), however that might not be what you want for your game. With this formula, there might be some “sliding” of segments around tightly knit curves. It should however get you started until you implement something more complex.

As with calculus: If you want to avoid “sliding” subdivide your snake into as many discreet pieces as you can. ex: Instead of adding a 5 pixel segment every time the snake eats something, add 5x one pixel segments. This will allow you to simulate a “continous” snake. Hint: If this hinders your rendering methods, you don't have to render every one of the 5 segments. You could render gap the middle segment as a bigger segment, but check collisions against the smaller ones.

The other solution (more percise [and much harder] ) is to stay with a discreet model, and only choose speeds which are whole integers of the segment lengths. You could still use an array then, because your snake, and all of it's movement are still discreet. However, unless this is a 2d game, it would make the rendering algorithm much harder.

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees

I made a Javascript implementation of this, it works for the most part but the distance

between the sections still increses when changing the speed. The distance doesn't increse

between the head and the first section, but increses bewteen the rest.

I put it in a fiddle to see the effect. Press "A" and "S" keys to change the speed

https://jsfiddle.net/9pmvtfcw/

I managed to get it to work. I needed to change the loop from back to foreward to foreward to back. One more thing left, how can I make the section rotate. For every section, setting the current angle to the angle in front doesn't give the right result. Thank you

Advertisement

to turn the "direction” vector into a 2d angle, simply use the trigonometric atan() function. Or you could use the dot product with the 0deg vector.

Whatever is easier for you…

My Oculus Rift Game: RaiderV

My Android VR games: Time-Rider& Dozer Driver

My browser game: Vitrage - A game of stained glass

My android games : Enemies of the Crown & Killer Bees

This topic is closed to new replies.

Advertisement