保存 Snake 的位置并检测与自身的碰撞。怎么了?

Save position of Snake and Detect Collison with it self. Whats wrong?

using System;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Drawing;
using OpenTK;
using OpenTK.Graphics.OpenGL;
using OpenTK.Graphics;

namespace Snake
    {
    public partial class GameWindow : Form
    {
    private int glcontrolFieldWidth = 20, glcontrolFieldHeight = 20; //Playing Field 
    public int speedincr = 0; //Speed, Increase by 5% Check out GenerateFood()
    public int GamePoints = -10; //Score 
    private int shaderProgram, color_attribute; //Shader Program
    private int view, model, projection;//Shader Program
    private Matrix4 ViewMatrix, ModelMatrix, ProjectionMatrix; // Matrix4
    private List<Point> snake = new List<Point>() { new Point(1, 1) }; //Where the Snake Start off
    private Point snakeDirection = new Point(1, 0);//Snake Direction
    private Point mouse = new Point(); //Food
    private Random random = new Random(); //Random Genereator 
    public bool bGameOver;
    private static readonly Timer timer = new Timer();

    public GameWindow()
    {
        //Form1.Designer
        InitializeComponent();

        // Centers the form on the current screen
        CenterToScreen();

        // Create a timer 
        //var timer = new Timer();
        timer.Tick += new EventHandler(GameLoop);
        timer.Interval = 150; // This is the snake inital speed
        timer.Start();

        // Generate an initial random position for the food
        GenerateFood();
    }

    public void GameOver(bool bGameOver)
    {
        //Snake Collision with its own body
        //for (int i = 0; i < snake.Count; i++)
        //{
        //    //if Snake equal itself then snake hasn't touch any other parts of its body
        //    if (snake[0].X == snake[i].X || snake[0].Y == snake[i].Y)
        //    {
        //        this.bGameOver = false;
        //        //Console.WriteLine("Snake " + snake2[i].X + "," + snake2[i].Y);
        //        //Console.WriteLine("Snake2 " + snake[i].X + "," + snake[i].Y);
        //    }
        //    else
        //    {
        //        this.bGameOver = true;
        //        //Console.WriteLine(snake[i].X+","+snake[i].Y);
        //    }
        //}



        ////---Display GameOver Message If Where Dead-- - //

        //if (bGameOver == true)
        //{
        //    Console.WriteLine("Game Over! Push Enter to Continue");
        //    if (bGameOver == false)
        //    {
        //        //Game Start Over

        //    }
        //}
        return;
    } //GameOver Reset Game

    public void GameLoop(object sender, System.EventArgs e)
    {
        // Update coordinates of game entities and check collisions
        Update();
        // UpdateWall check collisions with snake to bounce off wall
        UpdateWall();
        GameOver(bGameOver);
        glControl.Invalidate();
    } //Basic of the Game Loop

    private void UpdateWall()
    {
        // Snake collison with Walls
        if (snake[0].X < 1)
        {
            //snake[0].X = (glcontrolFieldWidth - 2) / 10; //Warp to right
            //snakeDirection.X = (snake[0].X + glcontrolFieldWidth-2)/10;
            //snakeDirection.X = (glcontrolFieldWidth-2)/10;
            snakeDirection.X = (int)(glcontrolFieldWidth-0.5) / 10;
            snakeDirection.Y = (int)(glcontrolFieldWidth-0.5) / 10;
            Console.WriteLine("Snake hit left wall");
        }
        else if (snake[0].X > glcontrolFieldWidth - 2)
        {
            //snakeDirection.X = 0; //Warp to left
            snakeDirection.X = (int)(glcontrolFieldWidth - 0.5) / -10;
            snakeDirection.Y = (int)(glcontrolFieldWidth - 0.5) / -10;
            Console.WriteLine("Snake hit right wall");
        }

        if (snake[0].Y < 1)
        {
            //snake.getFirst().y = windowHeight / 10; //Warp to bottom
            //snakeDirection.Y = (snake[0].Y + glcontrolFieldWidth - 2)/10;
            snakeDirection.X = (int)(glcontrolFieldHeight - 0.5)/10;
            snakeDirection.Y = (int)(glcontrolFieldHeight - 0.5)/10;
            Console.WriteLine("Snake hit Top wall");
        }
        else if (snake[0].Y > glcontrolFieldHeight - 2)
        {
            //snake.getFirst().y = 0; //Warp to top
            snakeDirection.X = (int)(glcontrolFieldHeight - 0.5) / -10;
            snakeDirection.Y = (int)(glcontrolFieldHeight - 0.5) / -10;
            Console.WriteLine("Snake hit Bottom wall");
        }

    } //Wall Collision

    private new void Update()
    {
        // Calculate a new position of the head of the snake
        Point newHeadPosition = new Point(snake[0].X + snakeDirection.X, snake[0].Y + snakeDirection.Y);
        // Insert new position in the beginning of the snake list
        snake.Insert(0, newHeadPosition);
        snake.RemoveAt(snake.Count - 1);

        // Check snake collision with the food
        if (snake[0].X != mouse.X || snake[0].Y != mouse.Y)
        {
            return;
        }
        else
        {
            //Snake Grow
            snake.Add(new Point(mouse.X, mouse.Y));
        }
        Console.WriteLine();

        //foreach (Point aPart in snake)
        //{
        //    Console.WriteLine(aPart);
        //}

        // Generate a new food(mouse) position
        GenerateFood();

    }//...more code.

GitHub @mrcoffeecode Snake Game C# 中的其余代码。我设法创造了墙、食物和蛇。还有食物和墙壁的检测。现在我一直在试图弄清楚游戏结束基本上是蛇检测到它自己被咬了。代码已经准备好 运行 没有任何错误你只需要 opentk,opengl,openglcontrol.dll.

蛇头是否撞到body就可以判断了。测试 snake[0] 是否命中从 1 到 snake.Count-1 的任何元素。 您必须验证 x 分量和 (&&) y 分量是否相等:

//Snake Collision with its own body
for (int i = 1; i < snake.Count; i++)
{
    //if Snake equal itself then snake hasn't touch any other parts of its body
    if (snake[0].X == snake[i].X && snake[0].Y == snake[i].Y)
    {
        this.bGameOver = true;
        break;
    }
}

请注意,在您的代码中,每当蛇长大时,都会检测到头部与 body 的碰撞,因为您在 had 位置插入了一个新元素。
如果你只是避免删除蛇的尾部元素,你可以摆脱设置:

private new void Update()
{
    // Calculate a new position of the head of the snake
    Point newHeadPosition = new Point(snake[0].X + snakeDirection.X, snake[0].Y + snakeDirection.Y);
    // Insert new position in the beginning of the snake list
    snake.Insert(0, newHeadPosition);
    # snake.RemoveAt(snake.Count - 1); <--------- DELETE    

    // Check snake collision with the food
    if (snake[0].X != mouse.X || snake[0].Y != mouse.Y)
    {
        # remove tail if snake does not grow
        snake.RemoveAt(snake.Count - 1); # <---------- ADD
        return;
    }
    else
    {
        //Snake Grow
        // snake.Add(new Point(mouse.X, mouse.Y)); <------ DELETE
    }
    Console.WriteLine();

    // Generate a new food(mouse) position
    GenerateFood();

} //Events