首页 > 解决方案 > 如何在 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);
            }
        }
    }
}'

标签: c#visual-studioterminalconsole

解决方案


你的代码有它需要的所有部分;你在主循环开始之前构建你的游戏状态,然后你正在检查用户输入,执行碰撞检测,检查游戏结束场景,在屏幕上的特定位置绘制蛇体的更新等。

墙的行为及其碰撞检查与蛇体的行为没有太大区别,但是设置墙是您想要在主游戏循环之前做的事情,并且不需要排队/ dequeueed 像蛇的身体位置。

如果你在你的主游戏循环开始之前添加一些设置代码ListPosition存储墙壁然后生成一个for循环来尝试将墙壁的位置添加到列表中并根据控制台的大小将它们绘制到控制台怎么办?窗户?您知道控制台的xy约束,因为您已经在检查蛇头的位置时使用了它们;在您的主游戏循环中,您可以像检查蛇身位置列表一样检查与墙壁位置列表的碰撞,并让您的游戏做出相应的行为。

将问题分解为离散的步骤可能是一个好的开始。

  1. 如何在控制台上绘制一个矩形?
  2. 如何在游戏开始前绘制该矩形?
  3. 如何使矩形填充我想要的空间?
  4. 如何跟踪绘制矩形的位置,以便检查蛇是否撞到它?
  5. 如何在主游戏循环期间检查蛇是否撞到墙壁位置之一?

推荐阅读