Visual Studio控制台中的文本垂直行距与可执行文件生成的控制台不一致
我在Visual Studio中做一个ASCII蛇游戏,当我用F5运行并构建时它可以工作,但当我运行生成的.exe文件或该文件的快捷方式时,字符之间的竖直间距太大,某些行甚至超出了屏幕/标题栏。如何在.exe文件以及桌面快捷方式的格式上解决这个问题?如果你需要我的代码,下面有。我已经尝试过设置缓冲区和设置窗口尺寸,但都没有效果。截图中水平的x 之间只有一个空格字符,垂直方向除了行距之外没有其他空格。
更新:我又做了更多测试,发现它在控制台中按预期行之间多写了一行。我也在朋友的电脑上运行过,它对他而言没问题,但在我这里却不行。
图片:
这是它不应该是这样的时候,且被拉伸了:

在这个版本中,x之间的水平间距与正确版本中的竖向间距相同,但竖直间距错误。
这是正确的,但只有在 Visual Studio 下才能这样运行:

代码:
代码:
using System;
using System.Data;
using System.Net.Http.Headers;
using System.Security.Cryptography;
using System.Text;
using System.Threading;
namespace Snake_Game
{
public static class Program
{
public static ScreenCompiler screen;
public static List<SnakePart> parts = new List<SnakePart>();
public static Apple[,] food;
public static int partNum;
public static void UpdateFood()
{
for (int x = 0; x < screen.screenx; x++)
{
for (int y = 0; y < screen.screeny; y++)
{
if (food[x, y] != null)
{
food[x, y].Update();
}
}
}
}
static void Main()
{
Console.WriteLine("Hit enter to start.");
Console.ReadLine();
Console.WriteLine("Use W, A, S, and D to control the snake.");
Thread.Sleep(1000);
Console.Clear();
Console.SetWindowSize(120, 30);
Console.SetBufferSize(120, 30);
Console.SetCursorPosition(0, 0);
Console.Clear();
Thread.Sleep(1000);
Console.CursorVisible = false;
Console.Beep(600, 60);
Console.Beep(900, 60);
Console.Beep(1200, 100);
screen = new ScreenCompiler(120, Console.LargestWindowHeight);
food = new Apple[screen.screenx, screen.screeny];
parts.Add(new SnakePart(20, 5, 0, 0));
parts.Add(new SnakePart(19, 5, 1, 0));
parts.Add(new SnakePart(18, 5, 2, 0));
partNum = 3;
int tick = 20;
Random rng = new Random();
while (true)
{
ConsoleKeyInfo key = new ConsoleKeyInfo('\0',ConsoleKey.None, false, false, false);
if (Console.KeyAvailable) {
key = Console.ReadKey();
}
if (key.Key == ConsoleKey.W)
{
if (parts[0].dir != 3 && parts[0].dir != 1) { parts[0].dir = 1; Console.Beep(600, 20); }
}
if (key.Key == ConsoleKey.A)
{
if (parts[0].dir != 0 && parts[0].dir != 2) { parts[0].dir = 2; Console.Beep(600, 20); }
}
if (key.Key == ConsoleKey.S)
{
if (parts[0].dir != 1 && parts[0].dir != 3) { parts[0].dir = 3; Console.Beep(600, 20); }
}
if (key.Key == ConsoleKey.D)
{
if (parts[0].dir != 2 && parts[0].dir != 0) { parts[0].dir = 0; Console.Beep(600, 20); }
}
int boost = partNum;
if (boost > 50)
{
boost = 50;
}
Thread.Sleep(80 - boost);
Console.SetCursorPosition(0, 0);
screen = new ScreenCompiler(Console.WindowWidth, Console.WindowHeight);
string score = "Score: " + partNum;
for (int i = 0; i < score.Length; i++)
{
screen.lines[0][i] = score[i];
}
tick--;
if (tick <= 0)
{
tick = 20;
int x = rng.Next(1, screen.screenx);
int y = rng.Next(1, screen.screeny);
food[x,y] = new Apple(x,y);
new Thread(() =>
{
Console.Beep(1000, 20);
}).Start();
}
for (int i = parts.Count - 1; i > -1; i--)
{
parts[i].Update();
}
for (int i = screen.screeny - 1; i > -1; i--)
{
Console.WriteLine(screen.lines[i]);
}
}
}
}
public class ScreenCompiler
{
public StringBuilder[] lines;
public int screenx;
public int screeny;
public ScreenCompiler(int screenx, int screeny)
{
this.screenx = screenx;
this.screeny = screeny;
lines = new StringBuilder[screeny];
StringBuilder def = new StringBuilder();
for (int i = 0; i < screenx; i++)
{
def.Append(' ');
}
for (int i = 0;i < screeny; i++)
{
lines[i] = new StringBuilder(def.ToString());
}
}
}
public class SnakePart
{
public int count;
public int x;
public int y;
public int? dir;
public SnakePart(int x, int y, int count, int? dir = null)
{
if (count == 0 && dir == null)
{
throw new ArgumentException("dir is required when part count is 0");
}
this.x = x;
this.y = y;
this.count = count;
this.dir = dir;
}
public void Update()
{
if (count == 0)
{
if (dir == 0)
{
x += 1;
Program.UpdateFood();
x += 1;
Program.UpdateFood();
} else if (dir == 1)
{
y += 1;
Program.UpdateFood();
} else if (dir == 2)
{
x -= 1;
Program.UpdateFood();
x -= 1;
Program.UpdateFood();
} else
{
y -= 1;
Program.UpdateFood();
}
try
{
if (Program.screen.lines[y][x] == 'x')
{
Console.WriteLine("Game Over!");
Console.Beep(900, 100);
Console.Beep(700, 100);
Console.Beep(500, 150);
Environment.Exit(0);
}
Program.screen.lines[y][x] = 'c';
} catch
{
Console.WriteLine("Game Over!");
Console.Beep(900, 100);
Console.Beep(700, 100);
Console.Beep(500, 150);
Environment.Exit(0);
}
} else
{
SnakePart s = Program.parts[count - 1];
if (s.x > x && s.x - x != 0)
{
dir = 0;
}
else if (s.x < x && s.x - x != 0)
{
dir = 2;
}
else if (s.y > y && s.y - y != 0)
{
dir = 1;
}
else
{
dir = 3;
}
x = s.x;
y = s.y;
try
{
Program.screen.lines[y][x] = 'x';
} catch
{
Console.WriteLine("Game Over!");
Console.Beep(900, 100);
Console.Beep(700, 100);
Console.Beep(500, 150);
Environment.Exit(0);
}
}
}
}
public class Apple
{
public int x;
public int y;
public Apple(int x, int y)
{
this.x = x;
this.y = y;
}
public void Update()
{
Program.screen.lines[y][x] = 'a';
if (Math.Abs(Program.parts[0].x - x) <= 2 && Math.Abs(Program.parts[0].y - y) <= 1)
{
int newx = 0;
int newy = 0;
if (Program.parts[Program.parts.Count - 1].dir == 0)
{
newx = -1;
} else if (Program.parts[Program.parts.Count - 1].dir == 1)
{
newy = -1;
} else if (Program.parts[Program.parts.Count - 1].dir == 2)
{
newx = 1;
} else if (Program.parts[Program.parts.Count - 1].dir == 3)
{
newy = 1;
}
Program.parts.Add(new SnakePart(Program.parts[Program.parts.Count - 1].x + newx, Program.parts[Program.parts.Count - 1].y + newy, Program.partNum));
Program.partNum++;
Console.Beep(800, 200);
Program.food[x, y] = null;
}
}
}
}
解决方案
我修好了。问题在于无论使用哪种控制台系统,只要文本到达缓冲区末端就会自动换行。我在代码中也把每行末尾设成换行,因此在Visual Studio之外的控制台里每行之间多出了一行。因此解决办法是把需要打印的所有文本拼成一个大字符串,输出时不带任何换行符。
站内所有文章版权归属LeftHeroAI导航站,无授权禁止任何主体转载、抄袭、复制内容,亦不得私自架设镜像站点。一经侵权,本站将通过法律途径追责。