保存 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
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