我正在寫一個c#控制檯俄羅斯方塊遊戲。一旦我找到了應用程序準備就緒的部分。我到了必須解決滯後的部分。我寫出來是這樣的:Pinvoke。加快Console.Write();
static void writeCol(string a, ConsoleColor b)
{
ConsoleColor c = Console.ForegroundColor;
Console.ForegroundColor = b;
Console.Write(a);
Console.ForegroundColor = c;
}
因此,當一個新的塊來/我想移動somehing:
writeCol(blokk, ConsoleColor.Magenta);
其中blokk是:
private const string blokk = "█";
我已經找到一種方法以更快的速度「寫入」控制檯:
using System;
using System.IO;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace ConsoleApplication1
{
class Program
{
[DllImport("Kernel32.dll", SetLastError = true, CharSet = CharSet.Auto)]
static extern SafeFileHandle CreateFile(
string fileName,
[MarshalAs(UnmanagedType.U4)] uint fileAccess,
[MarshalAs(UnmanagedType.U4)] uint fileShare,
IntPtr securityAttributes,
[MarshalAs(UnmanagedType.U4)] FileMode creationDisposition,
[MarshalAs(UnmanagedType.U4)] int flags,
IntPtr template);
[DllImport("kernel32.dll", SetLastError = true)]
static extern bool WriteConsoleOutput(
SafeFileHandle hConsoleOutput,
CharInfo[] lpBuffer,
Coord dwBufferSize,
Coord dwBufferCoord,
ref SmallRect lpWriteRegion);
[StructLayout(LayoutKind.Sequential)]
public struct Coord
{
public short X;
public short Y;
public Coord(short X, short Y)
{
this.X = X;
this.Y = Y;
}
};
[StructLayout(LayoutKind.Explicit)]
public struct CharUnion
{
[FieldOffset(0)] public char UnicodeChar;
[FieldOffset(0)] public byte AsciiChar;
}
[StructLayout(LayoutKind.Explicit)]
public struct CharInfo
{
[FieldOffset(0)] public CharUnion Char;
[FieldOffset(2)] public short Attributes;
}
[StructLayout(LayoutKind.Sequential)]
public struct SmallRect
{
public short Left;
public short Top;
public short Right;
public short Bottom;
}
[STAThread]
static void Main(string[] args)
{
SafeFileHandle h = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
if (!h.IsInvalid)
{
CharInfo[] buf = new CharInfo[80 * 25];
SmallRect rect = new SmallRect() { Left = 0, Top = 0, Right = 80, Bottom = 25 };
for (byte character = 65; character < 65 + 26; ++character)
{
for (short attribute = 0; attribute < 15; ++attribute)
{
for (int i = 0; i < buf.Length; ++i)
{
buf[i].Attributes = attribute;
buf[i].Char.AsciiChar = character;
}
bool b = WriteConsoleOutput(h, buf,
new Coord() { X = 80, Y = 25 },
new Coord() { X = 0, Y = 0 },
ref rect);
}
}
}
Console.ReadKey();
}
}
}
(此代碼打印出A-Z中的所有字符)。 所以finnaly問題: 我如何修改此代碼以利用它?
在此先感謝。祝你今天愉快。
編輯: 我發現1點的方式,但它給了我車的文本。有任何想法嗎?
public static void Writetocol(string s)
{
var kiir = s;
byte[] barr;
kiir = Convert.ToString(kiir);
barr = Encoding.ASCII.GetBytes(kiir);
SafeFileHandle h = CreateFile("CONOUT$", 0x40000000, 2, IntPtr.Zero, FileMode.Open, 0, IntPtr.Zero);
if (!h.IsInvalid)
{
CharInfo[] buf = new CharInfo[80 * 25];
SmallRect rect = new SmallRect() { Left = 0, Top = 0, Right = 80, Bottom = 25 };
for (short attribute = 0; attribute < 15; ++attribute)
{
for (int i = 0; i < barr.Length; ++i)
{
buf[i].Attributes = attribute;
buf[i].Char.AsciiChar = barr[i];
}
bool b = WriteConsoleOutput(h, buf,
new Coord() { X = 80, Y = 25 },
new Coord() { X = 0, Y = 0 },
ref rect);
}
}
}
它給了我這樣的: 當它應該給我:
(這是寫匈牙利如果有人懷疑)
使用的本地通話閱讀起來。你想知道的是*爲什麼*這個片段很快,你如何利用它。如果你模擬Console.Write(),那麼它將再次變得緩慢。 – 2015-02-08 21:48:41
謝謝我編輯了這個問題。 – 2015-02-08 22:00:58
現在的問題是,如果你想利用緩衝區,你不能使用控制字符(你在你的字符串中)。在數組緩衝區中,元素[0]在屏幕上的位置爲0,0。元素79在屏幕上的位置80,0。元素80的位置是0,1(這是下一行)。如果你的程序現在似乎假設逐行(和char字符)集合,你現在必須重新思考並重構爲逐個屏幕的方法。 – rene 2015-02-08 22:08:47