Snake Game pieces following head problem free movement(no grid)

Hey, I'm trying to make a snake game with free movement. I've got the head of the snake moving about perfectly, but I'm having trouble with the math to make all the other parts follow behind. There is no grid, so that's out! So far all I have is a second piece starting with the head, then it flies off the screen, whoops. I'm using allegro 5 to generate the graphics of the game if you want to try it out, but I really just need some math help. Thanks!

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

void SnakeManager::moveBits()
{
	//head
	SnakeBit* pHead = mSnakeMap[0];
	int snakeLength = mSnakeMap.size() - 1;

	pHead->addVelocityX(cos(pHead->getAngle()) * mForwardSpeed);
	pHead->addVelocityY(sin(pHead->getAngle()) * mForwardSpeed);

	Vector2D newLoc(pHead->getX(), pHead->getY());
	mSnakeMap[0]->setLoc(newLoc);

	//following pieces
	if (mIsLongEnough)
	{
		std::map<int, SnakeBit*>::iterator iter;

		iter = mSnakeMap.begin();
		std::advance(iter, 1);
		for (; iter != mSnakeMap.end(); ++iter)
		{
			SnakeBit* prevBit = mSnakeMap[iter->first - 1];
			SnakeBit* currentBit = mSnakeMap[iter->first];

			float xChange = prevBit->getX() - currentBit->getX();
			float yChange = prevBit->getY() - currentBit->getY();

			float angle = atan2(yChange, xChange);

			currentBit->addVelocityX(prevBit->getX() - cos(angle) * mForwardSpeed);
			currentBit->addVelocityY(prevBit->getY() - sin(angle) * mForwardSpeed);

			Vector2D newLoc(currentBit->getX(), currentBit->getY());
			mSnakeMap[iter->first]->setLoc(newLoc);
		}
	}
}

//all the function that change the velocity and angles and location
float getX(){ return mLocX; };
	float getY(){ return mLocY; };
	float getVelocityX(){ return mVelocityX; };
	float getVelocityY(){ return mVelocityY; };
	float getAngle(){ return mAngle; };

	void setPrev(Vector2D prev, int position){ mPrev[position] = prev; };
	void setX(float locX){ mLocX = locX; };
	void setY(float locY){ mLocX = locY; };
	void addVelocityX(float velocityX){ mLocX += velocityX; };
	void addVelocityY(float velocityY){ mLocY += velocityY; };
	void setAngle(float ang, bool isLeft){ isLeft ? mAngle -= ang : mAngle += ang; };
I didn't really look at the code, but my first thought would be to have a movement queue, maybe coupled with some timestamps.

Basically, you would log the direction the head moved along with the time of the movement into a big list. The rest of the snake segments would walk through that list performing the same step, but each segment would delay the timestamp a bit more.

Once the tail performs the step, it can be removed from the queue.
Let me get this straight, there will be a queue with a location far enough back for even the 300th piece. With each piece that's added the queue gets longer, but once the tail moves along it dequeues. But there needs to be a delay in between each or else they'll be on top of each other. O.K. I think it'll work! I hope the queue doesn't slow down the program too much.
Topic archived. No new replies allowed.