周末无聊准备自己写一个小游戏玩玩,结果写了一上午的贪吃蛇bug重重,根本没法玩(水平太菜,惭愧,惭愧)。然后去github找了一个写好的游戏,自己过了一遍,然后加上了注释。也做了一些小小的改动,玩起来还蛮好玩的,记录一下。
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Collections;
using System.Threading;
using System.Drawing;
namespace Snake
{
struct Position
{
public int row;
public int col;
public Position(int row, int col)
{
this.row = row;
this.col = col;
}
}
public class ConsoleRectangle
{
private int hWidth;
private int hHeight;
private Point hLocation;
private ConsoleColor hBorderColor;
public ConsoleRectangle(int width, int height, Point location, ConsoleColor borderColor)
{
hWidth = width;
hHeight = height;
hLocation = location;
hBorderColor = borderColor;
}
public Point Location
{
get { return hLocation; }
set { hLocation = value; }
}
public int Width
{
get { return hWidth; }
set { hWidth = value; }
}
public int Height
{
get { return hHeight; }
set { hHeight = value; }
}
public ConsoleColor BorderColor
{
get { return hBorderColor; }
set { hBorderColor = value; }
}
public void Draw()
{
string s = "╔";
string space = "";
string temp = "";
for (int i = 0; i < Width; i++)
{
space += " ";
s += "═";
}
for (int j = 0; j < Location.X; j++)
temp += " ";
s += "╗" + "\n";
for (int i = 0; i < Height; i++)
s += temp + "║" + space + "║" + "\n";
s += temp + "╚";
for (int i = 0; i < Width; i++)
s += "═";
s += "╝" + "\n";
Console.ForegroundColor = BorderColor;
Console.CursorTop = hLocation.Y;
Console.CursorLeft = hLocation.X;
Console.Write(s);
Console.ResetColor();
}
}
class Program
{
static void SnakeGame()
{
Console.WindowHeight = 50;
//Console.WindowWidth = 50;
byte right = 0;
byte left = 1;
byte down = 2;
byte up = 3;
int lastFoodTime = 0;
int foodDissapearTime = 8000;
int negativePoints = 0;
Position[] directions = new Position[]
{
new Position(0, 1), // right
new Position(0, -1), // left
new Position(1, 0), // down
new Position(-1, 0), // up
};
double sleepTime = 100;
int direction = right;// 蛇的默认移动方向
Random randomNumbersGenerator = new Random();
Console.BufferHeight = Console.WindowHeight;
lastFoodTime = Environment.TickCount;
List<Position> obstacles = new List<Position>()
{
new Position(12, 12),
new Position(14, 20),
new Position(7, 7),
new Position(19, 19),
new Position(6, 9),
};
foreach (Position obstacle in obstacles)
{
Console.ForegroundColor = ConsoleColor.Cyan;
Console.SetCursorPosition(obstacle.col, obstacle.row);
Console.Write("E");
}
// 蛇的身长的队列,如果吃了食物直接加一个进来,初始的蛇身长是6个*
Queue<Position> snakeElements = new Queue<Position>();
for (int i = 0; i <= 5; i++)
{
snakeElements.Enqueue(new Position(0, i));
}
// 随机生成一个食物的位置
// 食物生成完成后判断食物生成的位置与现在的蛇的身体或者障碍物有冲突
// 食物的位置与蛇的身体或者障碍物冲突了,那么一直重新生成食物,直到生成不冲突的食物
Position food;
do
{
food = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight),
randomNumbersGenerator.Next(0, Console.WindowWidth));
}
while (snakeElements.Contains(food) || obstacles.Contains(food));
Console.SetCursorPosition(food.col, food.row);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("@");// 第一次生成食物位置
foreach (Position position in snakeElements)
{
Console.SetCursorPosition(position.col, position.row);
Console.ForegroundColor = ConsoleColor.DarkGray;
Console.Write("*");
}
// 游戏的主循环
while (true)
{
negativePoints++;
if (Console.KeyAvailable)
{
ConsoleKeyInfo userInput = Console.ReadKey();
if (userInput.Key == ConsoleKey.LeftArrow)
{
if (direction != right) direction = left;
}
if (userInput.Key == ConsoleKey.RightArrow)
{
if (direction != left) direction = right;
}
if (userInput.Key == ConsoleKey.UpArrow)
{
if (direction != down) direction = up;
}
if (userInput.Key == ConsoleKey.DownArrow)
{
if (direction != up) direction = down;
}
}
// 蛇的头部
Position snakeHead = snakeElements.Last();
Position nextDirection = directions[direction];
Position snakeNewHead = new Position(snakeHead.row + nextDirection.row,
snakeHead.col + nextDirection.col);
// 判断蛇的头部位置是否超出窗口
if (snakeNewHead.col < 0) snakeNewHead.col = Console.WindowWidth - 1;
if (snakeNewHead.row < 0) snakeNewHead.row = Console.WindowHeight - 1;
if (snakeNewHead.row >= Console.WindowHeight) snakeNewHead.row = 0;
if (snakeNewHead.col >= Console.WindowWidth) snakeNewHead.col = 0;
// 第一个是判断蛇是否碰到了自己的身体,第二是判断蛇是否碰到了障碍物
// 如果进了这个判断,那么游戏结束,程序退出
if (snakeElements.Contains(snakeNewHead) || obstacles.Contains(snakeNewHead))
{
Console.SetCursorPosition(0, 0);
Console.ForegroundColor = ConsoleColor.Red;
Console.WriteLine("Game over!");
int userPoints = (snakeElements.Count - 6) * 100 - negativePoints;
//if (userPoints < 0) userPoints = 0;
userPoints = Math.Max(userPoints, 0);
Console.WriteLine("Your points are: {0}", userPoints);
return;
}
Console.SetCursorPosition(snakeHead.col, snakeHead.row);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("*");
//Console.SetCursorPosition(snakeNewHead.col, snakeNewHead.row);
//Console.ForegroundColor = ConsoleColor.DarkCyan;
//Console.Write("*");
snakeElements.Enqueue(snakeNewHead);
Console.SetCursorPosition(snakeNewHead.col, snakeNewHead.row);
Console.ForegroundColor = ConsoleColor.Gray;
if (direction == right) Console.Write(">");
if (direction == left) Console.Write("<");
if (direction == up) Console.Write("^");
if (direction == down) Console.Write("v");
if (snakeNewHead.col == food.col && snakeNewHead.row == food.row)
{
// feeding the snake
do
{
food = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight),
randomNumbersGenerator.Next(0, Console.WindowWidth));
}
while (snakeElements.Contains(food) || obstacles.Contains(food));
lastFoodTime = Environment.TickCount;
Console.SetCursorPosition(food.col, food.row);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("@");
sleepTime--;
Position obstacle = new Position();
do
{
obstacle = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight),
randomNumbersGenerator.Next(0, Console.WindowWidth));
}
while (snakeElements.Contains(obstacle) ||
obstacles.Contains(obstacle) ||
(food.row != obstacle.row && food.col != obstacle.row));
obstacles.Add(obstacle);
Console.SetCursorPosition(obstacle.col, obstacle.row);
Console.ForegroundColor = ConsoleColor.Cyan;
Console.Write("E");
}
else
{
// moving...
Position last = snakeElements.Dequeue();
Console.SetCursorPosition(last.col, last.row);
Console.Write(" ");
}
if (Environment.TickCount - lastFoodTime >= foodDissapearTime)
{
negativePoints = negativePoints + 50;
Console.SetCursorPosition(food.col, food.row);
Console.Write(" ");
do
{
food = new Position(randomNumbersGenerator.Next(0, Console.WindowHeight),
randomNumbersGenerator.Next(0, Console.WindowWidth));
}
while (snakeElements.Contains(food) || obstacles.Contains(food));
lastFoodTime = Environment.TickCount;
}
Console.SetCursorPosition(food.col, food.row);
Console.ForegroundColor = ConsoleColor.Yellow;
Console.Write("@");
sleepTime -= 0.01;
Thread.Sleep((int)sleepTime);
}
}
static void Main(string[] args)
{
SnakeGame();
}
}
}