c# - 如何在 C# 中为蛇游戏制作墙
问题描述
我做了一个蛇游戏,但现在我想在终端上添加功能,玩家可以选择游戏模式绑定模式(墙)和非绑定模式(无墙)。我想知道如何制作墙,因为我看到一些项目使用诸如“#”之类的符号,当蛇头撞到墙上时,玩家输掉了游戏。
' static void Main(string[] args)
{
byte right = 0;
byte left = 1;
byte down = 2;
byte up = 3;
int currentTime = Environment.TickCount;
int lastFoodTime = 0;
int foodDissapearTime = 10000; //food dissappears after 10 second
int negativePoints = 0;
Position[] directions = new Position[4];
Program p = new Program();
//display start screen before background music and game start
p.DisplayStartScreen();
//Play background music
p.BackgroundMusic();
// Define direction with characteristic of index of array
p.Direction(directions);
// Initialised the obstacles location at the starting of the game
List<Position> obstacles = new List<Position>();
p.InitialRandomObstacles(obstacles);
//Do the initialization for sleepTime (Game's Speed), Snake's direction and food timing
//Limit the number of rows of text accessible in the console window
double sleepTime = 100;
int direction = right;
Random randomNumbersGenerator = new Random();
Console.BufferHeight = Console.WindowHeight;
lastFoodTime = Environment.TickCount;
//Initialise the snake position in top left corner of the windows
//Havent draw the snake elements in the windows yet. Will be drawn in the code below
Queue<Position> snakeElements = new Queue<Position>();
for (int i = 0; i <= 3; i++) // Length of the snake was reduced to 3 units of *
{
snakeElements.Enqueue(new Position(0, i));
}
//To position food randomly when the program runs first time
Position food = new Position();
p.GenerateFood(ref food,snakeElements,obstacles);
//while the game is running position snake on terminal with shape "*"
foreach (Position position in snakeElements)
{
Console.SetCursorPosition(position.col, position.row);
p.DrawSnakeBody();
}
while (true)
{
//negative points is initialized as 0 at the beginning of the game. As the player reaches out for food
//negative points increment depending how far the food is
negativePoints++;
//Check the user input direction
p.CheckUserInput(ref direction, right, left, down, up);
//When the game starts the snake head is towards the end of his body with face direct to start from right.
Position snakeHead = snakeElements.Last();
Position nextDirection = directions[direction];
//Snake position to go within the terminal window assigned.
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;
//Check for GameOver Criteria
int gameOver=p.GameOverCheck(currentTime, snakeElements, snakeNewHead, negativePoints,obstacles);
if (gameOver == 1)
return;
//Check for Winning Criteria
int winning = p.WinningCheck(snakeElements, negativePoints);
if (winning == 1) return;
//The way snake head will change as the player changes his direction
Console.SetCursorPosition(snakeHead.col, snakeHead.row);
p.DrawSnakeBody();
//Snake head shape when the user presses the key to change his direction
snakeElements.Enqueue(snakeNewHead);
Console.SetCursorPosition(snakeNewHead.col, snakeNewHead.row);
Console.ForegroundColor = ConsoleColor.Gray;
if (direction == right) Console.Write(">"); //Snake head when going right
if (direction == left) Console.Write("<");//Snake head when going left
if (direction == up) Console.Write("^");//Snake head when going up
if (direction == down) Console.Write("v");//Snake head when going down
// food will be positioned randomly until they are not at the same row & column as snake head
if (snakeNewHead.col == food.col && snakeNewHead.row == food.row)
{
Console.Beep();// Make a sound effect when food was eaten.
p.GenerateFood(ref food, snakeElements, obstacles);
//when the snake eat the food, the system tickcount will be set as lastFoodTime
//new food will be drawn, snake speed will increases
lastFoodTime = Environment.TickCount;
sleepTime--;
//Generate new obstacle
p.GenerateNewObstacle(ref food,snakeElements,obstacles);
}
else
{
// snake is moving
Position last = snakeElements.Dequeue();
Console.SetCursorPosition(last.col, last.row);
Console.Write(" ");
}
//if snake did not eat the food before it disappears, 50 will be added to negative points
//draw new food after the previous one disappeared
if (Environment.TickCount - lastFoodTime >= foodDissapearTime)
{
negativePoints = negativePoints + 50;
Console.SetCursorPosition(food.col, food.row);
Console.Write(" ");
//Generate the new food and record the system tick count
p.GenerateFood(ref food, snakeElements, obstacles);
lastFoodTime = Environment.TickCount;
}
//snake moving speed increased
sleepTime -= 0.01;
//pause the execution thread of snake moving speed
Thread.Sleep((int)sleepTime);
}
}
}
}'
解决方案
你的代码有它需要的所有部分;你在主循环开始之前构建你的游戏状态,然后你正在检查用户输入,执行碰撞检测,检查游戏结束场景,在屏幕上的特定位置绘制蛇体的更新等。
墙的行为及其碰撞检查与蛇体的行为没有太大区别,但是设置墙是您想要在主游戏循环之前做的事情,并且不需要排队/ dequeueed 像蛇的身体位置。
如果你在你的主游戏循环开始之前添加一些设置代码List
来Position
存储墙壁然后生成一个for
循环来尝试将墙壁的位置添加到列表中并根据控制台的大小将它们绘制到控制台怎么办?窗户?您知道控制台的x
和y
约束,因为您已经在检查蛇头的位置时使用了它们;在您的主游戏循环中,您可以像检查蛇身位置列表一样检查与墙壁位置列表的碰撞,并让您的游戏做出相应的行为。
将问题分解为离散的步骤可能是一个好的开始。
- 如何在控制台上绘制一个矩形?
- 如何在游戏开始前绘制该矩形?
- 如何使矩形填充我想要的空间?
- 如何跟踪绘制矩形的位置,以便检查蛇是否撞到它?
- 如何在主游戏循环期间检查蛇是否撞到墙壁位置之一?
推荐阅读
- kotlin - 生成序列时抛出的异常
- amazon-web-services - aws redhat root密码是什么
- javascript - 使用 xml2js 将 JSON 文件转换为 XML 时如何删除空标签?
- ajax - Ajax回调不重建表单drupal 8
- sql - 交叉应用的 SQL 替代方案
- html - 文本不会在滚动效果背景图像中垂直居中
- javascript - 如何在 Material ui TablestickyHeader 的表头上应用 css?
- sql - 每天为特定条件下的记录创建一条记录
- visual-studio - 如何更改 SSRS rdl 的 ServerTargetVersion
- regex - 在 where 子句 pyspark 中使用正则表达式加入 2 个数据框