C# 在没有控制台的情况下写入控制台屏幕。设置光标位置(?,)

C# 在没有控制台的情况下写入控制台屏幕。设置光标位置(?,),c#,console,C#,Console,有没有一种方法可以在控制台窗口中以特定坐标写入字符串而不使用console.SetCursorPosition(?,)解决此问题的一般思路: 计算游戏的当前“框架”,它只是一行行完整的文本 清理控制台 将整个“框架”打印到控制台 等待输入,修改游戏中的对象,重复 例如,我写了下面的“控制台游戏”:玩家是一个“*”,其余的填充“-”。窗口会自动调整大小。玩家可以使用箭头键(左、右、上、下)向各个方向移动。没有进行错误检查 这是一个基本设置,使用StringBuilder对象数组可以轻松修改字符

有没有一种方法可以在控制台窗口中以特定坐标写入字符串而不使用console.SetCursorPosition(?,)

解决此问题的一般思路:

  • 计算游戏的当前“框架”,它只是一行行完整的文本
  • 清理控制台
  • 将整个“框架”打印到控制台
  • 等待输入,修改游戏中的对象,重复
例如,我写了下面的“控制台游戏”:玩家是一个“*”,其余的填充“-”。窗口会自动调整大小。玩家可以使用箭头键(左、右、上、下)向各个方向移动。没有进行错误检查

这是一个基本设置,使用
StringBuilder
对象数组可以轻松修改字符串(
strings
是不可变的)。不过,编写一个通用的
DrawTextInFramebuffer(字符串文本,int x,int y,framebuffer)

<> > >编辑< /St>:强制视频建议:C++中使用控制台窗口和彩色块的复古赛车游戏,虽然C实现也可能。

使用系统;
使用System.Linq;
使用系统文本;
命名空间堆栈溢出测试
{
班级计划
{
/*球员位置*/
静态整数PlayerX=1;
静态int PlayerY=1;
静态字符串ComputeFrameBuffer()
{
//控制台窗口的当前尺寸是多少
int consolewindowehight=控制台窗口高度;
int consoleWindowWidth=Console.WindowWidth-1;/-1可防止行溢出
//按行计算帧缓冲区
var lines=新的StringBuilder[控制台窗口];
对于(int y=0;yl.ToString());
}
静态void Main(字符串[]参数)
{
bool runGame=true;
while(runGame)
{
//渲染当前帧
字符串帧=ComputeFrameBuffer();
Console.Clear();
控制台。写入(帧);
//抓取下一个用户输入
var pressedKey=Console.ReadKey(false);
//处理事情
开关(按按键。按键)
{
case ConsoleKey.LeftArrow:
PlayerX--;
打破
case ConsoleKey.RightArrow:
PlayerX++;
打破
case ConsoleKey.UpArrow:
PlayerY--;//坐标系为左上=(0,0)。向下增加Y。
打破
case ConsoleKey.DownArrow:
PlayerY++;
打破
case ConsoleKey.逃生:
runGame=false;
打破
}
//钳制坐标始终在边界内
int maxY=Console.WindowHeight;
int maxX=Console.WindowWidth-1;
如果(PlayerX<0)PlayerX=0;
如果(PlayerX>=maxX)PlayerX=maxX-1;
如果(PlayerY<0)PlayerY=0;
如果(PlayerY>=maxY)PlayerY=maxY-1;
}
}
}
}

解决此问题的总体思路:

  • 计算游戏的当前“框架”,它只是一行行完整的文本
  • 清理控制台
  • 将整个“框架”打印到控制台
  • 等待输入,修改游戏中的对象,重复
例如,我写了下面的“控制台游戏”:玩家是一个“*”,其余的填充“-”。窗口会自动调整大小。玩家可以使用箭头键(左、右、上、下)向各个方向移动。没有进行错误检查

这是一个基本设置,使用
StringBuilder
对象数组可以轻松修改字符串(
strings
是不可变的)。不过,编写一个通用的
DrawTextInFramebuffer(字符串文本,int x,int y,framebuffer)

<> > >编辑< /St>:强制视频建议:C++中使用控制台窗口和彩色块的复古赛车游戏,虽然C实现也可能。

使用系统;
使用System.Linq;
使用系统文本;
命名空间堆栈溢出测试
{
班级计划
{
/*球员位置*/
静态整数PlayerX=1;
静态int PlayerY=1;
静态字符串ComputeFrameBuffer()
{
//控制台窗口的当前尺寸是多少
int consolewindowehight=控制台窗口高度;
int consoleWindowWidth=Console.WindowWidth-1;/-1可防止行溢出
//按行计算帧缓冲区
var lines=新的StringBuilder[控制台窗口];
对于(int y=0;yusing System;
using System.Linq;
using System.Text;

namespace StackOverflowTesting
{
    class Program
    {
        /* Player position */
        static int PlayerX = 1;
        static int PlayerY = 1;

        static string ComputeFrameBuffer()
        {
            //What are the current dimensions of the console window
            int consoleWindowHeight = Console.WindowHeight;
            int consoleWindowWidth = Console.WindowWidth - 1;  //-1 prevents line overflow

            //Compute framebuffer line-wise
            var lines = new StringBuilder[consoleWindowHeight];

            for(int y = 0; y < consoleWindowHeight; y++)
            {
                //Create the line as a repetition of consoleWindowWidth spaces or other filler.
                lines[y] = new StringBuilder(string.Join("", Enumerable.Repeat("-", consoleWindowWidth)));
                for (int x = 0; x < consoleWindowWidth; x++) 
                {
                    //What do we need to draw at this (x,y) position? is the player here? 
                    if(PlayerX == x && PlayerY == y)
                    {
                        //Yes. Use a '*' for the player "sprite"..
                        lines[y][x] = '*';
                    }
                }
            }
            //Concatinate all lines
            return string.Join("\n", lines.Select(l => l.ToString()));
        }

        static void Main(string[] args)
        {
            bool runGame = true;
            while (runGame)
            {
                //Render current frame
                string frame = ComputeFrameBuffer();
                Console.Clear();
                Console.Write(frame);

                //Grab next user input
                var pressedKey = Console.ReadKey(false);
                //Handle stuff
                switch (pressedKey.Key)
                {
                    case ConsoleKey.LeftArrow:
                        PlayerX--;
                        break;
                    case ConsoleKey.RightArrow:
                        PlayerX++;
                        break;
                    case ConsoleKey.UpArrow:
                        PlayerY--; //Coordinate system is upper left = (0,0). Downwards increases Y.
                        break;
                    case ConsoleKey.DownArrow:
                        PlayerY++;
                        break;
                    case ConsoleKey.Escape:
                        runGame = false;
                        break;
                }
                //clamp coordinates to be always within bounds
                int maxY = Console.WindowHeight;
                int maxX = Console.WindowWidth - 1; 
                if (PlayerX < 0) PlayerX = 0;
                if (PlayerX >= maxX) PlayerX = maxX - 1;
                if (PlayerY < 0) PlayerY = 0;
                if(PlayerY >= maxY) PlayerY = maxY - 1;
            }
        }
    }
}
switch (pressedKey.Key)
{
      case ConsoleKey.LeftArrow:
      {
           PlayerX--;
           if (PlayerX == -1)
               PlayerX++;
      } 
      break;
      case ConsoleKey.RightArrow:
      {
           PlayerX++;
           if(PlayerX == width-1)
              PlayerX--;
      } 
      break;
      case ConsoleKey.UpArrow:
      {
           PlayerY--;
           if (PlayerY == -1)
               PlayerY++;
      } 
      break;
      case ConsoleKey.DownArrow:
      {
           PlayerY++;
           if (PlayerY == height)
               PlayerY--;
      } 
      break;
      case ConsoleKey.E:
           runGame = false;
           break;
}