zencha
zencha

Reputation: 11

Snake body parts not positioning properly

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

Answers (1)

Bogdan
Bogdan

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

Related Questions