Reputation: 11
I have a mostly functioning snake game. Dude moves around, eats fruit, grows the body.
The added body parts are appearing immediately behind the previous snake piece, rather than appearing as a "chain" of sorts.
Code for updating and drawing body parts:
for (int i = snake.Count - 1; i >= 0; i--)
{
if (i == 0)
{
Snakepart head = snake[0];
// Collision with Screen Boundaries
if (head.snakePartRectangle.X <= 0 ||
head.snakePartRectangle.X >= screenWidth ||
head.snakePartRectangle.Y <= 0 ||
head.snakePartRectangle.Y >= screenHeight)
{
headExists = false;
}
//Collision with Body
//for (int j = 1; j < snake.Count; j++) {
// if (head.snakePartRectangle.Intersects(snake[j].snakePartRectangle))
// this.Exit ();
//}
// Collision with Food
if (head.snakePartRectangle.Intersects(foodRectangle))
{
Snakepart part = new Snakepart();
//part.snakePartRectangle = snake [snake.Count - 1].snakePartRectangle;
part.snakePosition.X = snake[snake.Count - 1].snakePosition.X;
part.snakePosition.Y = snake[snake.Count - 1].snakePosition.Y;
part.snakeTexture = this.Content.Load < Texture2D > ("pacman");
snake.Add(part);
foodEaten = true;
}
}
else if (i > 0)
{
snake[i].snakePosition = snake[i - 1].snakePosition;
}
}
base.Update(gameTime);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
// Clear the backbuffer
graphics.GraphicsDevice.Clear(Color.CornflowerBlue);
spriteBatch.Begin();
spriteBatch.Draw(foodTexture, foodRectangle, Color.White);
for (int i = 0; i < snake.Count; i++)
{
spriteBatch.Draw(snake[i].snakeTexture, snake[i].snakePosition, Color.Blue);
}
spriteBatch.End();
//TODO: Add your drawing code here
base.Draw(gameTime);
#endregion
}
Picture:
It's intended to be a chain of blue pacmans, not overlapped as in the image.
What is causing the body parts to snap to the previous one so tightly?
Edit: I added this to the logic that updates the body parts.
else if (i > 0) {
if (moveRight) {
snake [i].snakePosition.X = snake [i - 1].snakePosition.X - 26;
snake [i].snakePosition.Y = snake [i - 1].snakePosition.Y;
}
if (moveLeft) {
snake [i].snakePosition.X = snake [i - 1].snakePosition.X + 26;
snake [i].snakePosition.Y = snake [i - 1].snakePosition.Y;
}
if (moveUp) {
snake [i].snakePosition.X = snake [i - 1].snakePosition.X;
snake [i].snakePosition.Y = snake [i - 1].snakePosition.Y + 26;
}
if (moveDown) {
snake [i].snakePosition.X = snake [i - 1].snakePosition.X;
snake [i].snakePosition.Y = snake [i - 1].snakePosition.Y - 26;
}
}
Which has them spacing appropriately, but part of the problem is that it's repositioning at update rate so the body parts are not doing the classic "follow-the-leader" movement. Trying to figure that out now.
Picture:
If I change directions, they all move very quickly to the new direction. Slowing that down somehow would fix this I think.
Edit 2: Draw method requested
protected override void Draw (GameTime gameTime)
{
// Clear the backbuffer
graphics.GraphicsDevice.Clear (Color.CornflowerBlue);
spriteBatch.Begin ();
spriteBatch.Draw (foodTexture, foodRectangle, Color.White);
for (int i = 0; i < snake.Count; i++)
{
spriteBatch.Draw (snake [i].snakeTexture, snake [i].snakePosition, Color.Blue);
}
spriteBatch.End ();
//TODO: Add your drawing code here
base.Draw (gameTime);
#endregion
}
Upvotes: 1
Views: 581
Reputation: 484
This seems like a case of using the wrong data structure for the job. Using the list you need to update all parts positions and that is prone to errors.
I suggest using a queue and just en-queue new parts as a new head and dequeue parts from tail if the snake does not grow - this way you only need to recalculate new head position.
Upvotes: 1