问题描述
我有一个.cpp文件,它是俄罗斯方块的游戏代码:
#include <iostream>
#include <vector>
#include <string>
#include <random>
#include <Windows.h>
using namespace std;
const vector<vector<wstring>> tetromino = {
// I
{
L"....XX......XX......XX......XX..",// 0 deg
L"................XXXXXXXX........",// 90 deg
L"..XX......XX......XX......XX....",// 180 deg
L"........XXXXXXXX................" // 270 deg
},// J
{
L"....XX......XX....XXXX..........",L"..........XX......XXXXXX........",L"..........XXXX....XX......XX....",L"........XXXXXX......XX.........."
},// L
{
L"..XX......XX......XXXX..........",L"..........XXXXXX..XX............",L"..........XXXX......XX......XX..",L"............XX..XXXXXX.........."
},// O
{
L"..........XXXX....XXXX..........",L"..........XXXX....XXXX..........",L"..........XXXX....XXXX.........."
},// S
{
L"..XX......XXXX......XX..........",L"............XXXX..XXXX..........",L"..........XX......XXXX......XX..",L"..........XXXX..XXXX............"
},// T
{
L"..XX......XXXX....XX............",L"..........XXXXXX....XX..........",L"............XX....XXXX......XX..",L"..........XX....XXXXXX.........."
},// Z
{
L"....XX....XXXX....XX............",L"..........XXXX......XXXX........",L"............XX....XXXX....XX....",L"........XXXX......XXXX.........."
}
};
const int nScreenWidth = 39;
const int nScreenHeight = 21;
const int nBoardWidth = 22;
const int nBoardHeight = 21;
const wstring detail = L" ▓█░╚╝║═";
int random(int nMin,int nMax)
{
random_device rd;
mt19937 rng(rd());
uniform_int_distribution<int> uni(nMin,nMax);
auto num = uni(rng);
return num;
}
void Configure()
{
system("MODE 39,22");
system("color 89");
HANDLE hConsoleOutput = GetStdHandle(STD_OUTPUT_HANDLE);
CONSOLE_SCREEN_BUFFER_INFOEX csbiex;
csbiex.cbSize = sizeof(CONSOLE_SCREEN_BUFFER_INFOEX);
GetConsoleScreenBufferInfoEx(hConsoleOutput,&csbiex);
csbiex.ColorTable[0] = RGB(0,188,212);
csbiex.ColorTable[1] = RGB(63,81,181);
csbiex.ColorTable[2] = RGB(255,87,34);
csbiex.ColorTable[3] = RGB(255,235,59);
csbiex.ColorTable[4] = RGB(76,175,80);
csbiex.ColorTable[5] = RGB(156,39,176);
csbiex.ColorTable[6] = RGB(237,28,36);
csbiex.ColorTable[7] = RGB(242,242,242);
csbiex.ColorTable[8] = RGB(248,248,248);
csbiex.ColorTable[9] = RGB(20,20,20);
SetConsoleScreenBufferInfoEx(hConsoleOutput,&csbiex);
}
void Frame(wchar_t*& wcBuffer,wstring wsCaption,int nWidth,int nHeight,int nPosX,int nPosY)
{
for (int i = nPosX; i < nWidth + nPosX; i++)
{
for (int j = nPosY; j < nHeight + nPosY; j++)
{
if (i == nPosX)
{
if (j == nPosY)
{
wcBuffer[j * nScreenWidth + i] = L'╔';
}
else if (j == nHeight + nPosY - 1)
{
wcBuffer[j * nScreenWidth + i] = L'╚';
}
else
{
wcBuffer[j * nScreenWidth + i] = L'║';
}
}
else if (i == nWidth + nPosX - 1)
{
if (j == nPosY)
{
wcBuffer[j * nScreenWidth + i] = L'╗';
}
else if (j == nHeight + nPosY - 1)
{
wcBuffer[j * nScreenWidth + i] = L'╝';
}
else
{
wcBuffer[j * nScreenWidth + i] = L'║';
}
}
else
{
if (j == nPosY || j == nHeight + nPosY - 1)
{
wcBuffer[j * nScreenWidth + i] = L'═';
}
else
{
wcBuffer[j * nScreenWidth + i] = L' ';
}
}
}
}
int CapIndex = nPosY * nScreenWidth + (nPosX + 1);
for (int i = 0; i < wsCaption.length(); i++,CapIndex++)
{
wcBuffer[CapIndex] = wsCaption.at(i);
}
}
void Block(wchar_t*& pBuffer,WORD*& pColor,int nTetromino,int nPosY)
{
for (int j = 0; j < 4; j++)
{
for (int i = 0; i < 8; i++)
{
if (tetromino.at(nTetromino).at(0).at(j * 8 + i) != L'.')
{
pBuffer[(nPosY + j) * nScreenWidth + (nPosX + i)] = L'▓';
}
else
{
pBuffer[(nPosY + j) * nScreenWidth + (nPosX + i)] = L' ';
}
pColor[(nPosY + j) * nScreenWidth + (nPosX + i)] = 8 * 16 + nTetromino;
}
}
}
void Text(wchar_t*& pBuffer,wstring content,int nPosY)
{
for (int i = 0; i < content.length(); i++,nPosX++)
{
pBuffer[nPosY * nScreenWidth + nPosX] = content.at(i);
}
}
bool CheckPiece(int*& pMatrix,int nRotation,int nPosY)
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 4; j++)
{
if (nPosX + i >= 0 && nPosX + i < nBoardWidth)
{
if (nPosY + j >= 0 && nPosY + j < nBoardHeight)
{
if (tetromino.at(nTetromino).at(nRotation).at(j * 8 + i) != L'.' && pMatrix[(nPosY + j) * nBoardWidth + (nPosX + i)] != 0)
{
return 0;
}
}
}
}
}
return 1;
}
int main()
{
Configure();
WORD* pColor = new WORD[nScreenWidth * nScreenHeight];
wchar_t* pBuffer = new wchar_t[nScreenWidth * nScreenHeight];
for (int i = 0; i < nScreenWidth; i++)
{
for (int j = 0; j < nScreenHeight; j++)
{
pBuffer[j * nScreenWidth + i] = L' ';
if (i == 0 || i >= nBoardWidth - 1 || j == nBoardHeight - 1)
{
pColor[j * nScreenWidth + i] = 8 * 16 + 9;
}
else
{
if (j % 2 == 1)
{
if (i % 4 == 1 || i % 4 == 2)
{
pColor[j * nScreenWidth + i] = 8 * 16 + 9;
}
else
{
pColor[j * nScreenWidth + i] = 7 * 16 + 9;
}
}
else
{
if (i % 4 == 3 || i % 4 == 0)
{
pColor[j * nScreenWidth + i] = 8 * 16 + 9;
}
else
{
pColor[j * nScreenWidth + i] = 7 * 16 + 9;
}
}
}
}
}
int* pMatrix = new int[nBoardWidth * nBoardHeight];
for (int i = 0; i < nBoardWidth; i++)
{
for (int j = 0; j < nBoardHeight; j++)
{
if (j == nBoardHeight - 1)
{
if (i == 0)
{
pMatrix[j * nBoardWidth + i] = 4;
}
else if (i == nBoardWidth - 1)
{
pMatrix[j * nBoardWidth + i] = 5;
}
else
{
pMatrix[j * nBoardWidth + i] = 7;
}
}
else
{
if (i == 0 || i == nBoardWidth - 1)
{
pMatrix[j * nBoardWidth + i] = 6;
}
else
{
pMatrix[j * nBoardWidth + i] = 0;
}
}
}
}
HANDLE hConsole = CreateConsoleScreenBuffer(GENERIC_READ | GENERIC_WRITE,NULL,CONSOLE_TEXTMODE_BUFFER,NULL);
SetConsoleActiveScreenBuffer(hConsole);
DWORD dwBytesWritten = 0;
Frame(pBuffer,L"[ SCORE ]",17,3,nBoardWidth,1);
Frame(pBuffer,L"[ LINE ]",4);
Frame(pBuffer,L"[ NEXT ]",6,7);
const vector<char> key = { 'W','A','S','D' };
bool bKey[4];
int nCurrentPiece = random(0,6);
int nNextPiece = random(0,6);
int nCurrentRotation = 0;
int nCurrentX = nBoardWidth / 2 - 4;
int nCurrentY = 0;
int nFrame = 10;
int nFrameCount = 0;
bool bForceDown = 0;
bool bRotateHold = 1;
int nScore = 0;
int nScorePosX = 37;
int nScoreComp = 10;
int nLine = 0;
int nLinePosX = 37;
int nLineComp = 10;
vector<int> vLines;
bool bGameOver = 0;
while (bGameOver != 1)
{
// GAME TIMING
Sleep(75);
nFrameCount++;
if (nFrameCount == nFrame)
{
bForceDown = 1;
}
else
{
bForceDown = 0;
}
// INPUT
for (int i = 0; i < key.size(); i++)
{
if ((GetKeyState(key.at(i)) & 0x8000) != 0)
{
bKey[i] = 1;
}
else
{
bKey[i] = 0;
}
}
// GAME LOGIC
int nLimit = 0;
if (nCurrentPiece == 3)
{
nLimit = -1;
}
if (bKey[3] == 1 && nCurrentY >= nLimit)
{
if (CheckPiece(pMatrix,nCurrentPiece,nCurrentRotation,nCurrentX + 2,nCurrentY) == 1)
{
nCurrentX += 2;
}
}
if (bKey[1] == 1 && nCurrentY >= nLimit && CheckPiece(pMatrix,nCurrentX - 2,nCurrentY) == 1)
{
nCurrentX -= 2;
}
if (bKey[2] == 1 && nCurrentY >= nLimit)
{
int i{};
while (CheckPiece(pMatrix,nCurrentX,nCurrentY + i) == 1)
{
i++;
}
nCurrentY += i - 1;
}
if (bKey[0] == 1 && nCurrentY >= nLimit && bRotateHold == 1 && CheckPiece(pMatrix,(nCurrentRotation + 1) % 4,nCurrentY) == 1)
{
nCurrentRotation++;
nCurrentRotation %= 4;
bRotateHold = 0;
}
else
{
bRotateHold = 1;
}
if (bForceDown == 1)
{
nFrameCount = 0;
if (CheckPiece(pMatrix,nCurrentY + 1))
{
nCurrentY++;
}
else
{
if (nCurrentY < nLimit)
{
bGameOver = 1;
break;
}
else
{
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 4; j++)
{
if (nCurrentY >= 0 && tetromino.at(nCurrentPiece).at(nCurrentRotation).at(j * 8 + i) != L'.')
{
pMatrix[(nCurrentY + j) * nBoardWidth + (nCurrentX + i)] = 2;
if ((nCurrentY + j) % 2 == 1)
{
if ((nCurrentX + i) % 4 == 1 || (nCurrentX + i) % 4 == 2)
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
}
else
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
}
}
else
{
if ((nCurrentX + i) % 4 == 3 || (nCurrentX + i) % 4 == 0)
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
}
else
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
}
}
}
}
}
for (int j = 0; j < 4; j++)
{
if (nCurrentY + j < nBoardHeight - 1)
{
bool bLine = 1;
for (int i = 1; i < nBoardWidth - 1; i++)
{
if (pMatrix[(nCurrentY + j) * nBoardWidth + i] == 0)
{
bLine = 0;
break;
}
}
if (bLine == 1)
{
nLine++;
for (int i = 1; i < nBoardWidth - 1; i++)
{
pMatrix[(nCurrentY + j) * nBoardWidth + i] = 3;
}
vLines.push_back(nCurrentY + j);
}
}
}
nScore += 25;
if (!vLines.empty())
{
nScore += (1 << vLines.size()) * 100;
}
nCurrentX = nBoardWidth / 2 - 4;
nCurrentY = -4;
nCurrentRotation = 0;
nCurrentPiece = nNextPiece;
nNextPiece = random(0,6);
}
}
}
// DISPLAY
for (int i = 0; i < nBoardWidth; i++)
{
for (int j = 0; j < nBoardHeight; j++)
{
pBuffer[j * nScreenWidth + i] = detail[pMatrix[j * nBoardWidth + i]];
}
}
for (int i = 0; i < 8; i++)
{
for (int j = 0; j < 4; j++)
{
if (tetromino.at(nCurrentPiece).at(nCurrentRotation).at(j * 8 + i) != L'.' && nCurrentY + j >= 0)
{
if ((nCurrentY + j) % 2 == 1)
{
if ((nCurrentX + i) % 4 == 1 || (nCurrentX + i) % 4 == 2)
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
}
else
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
}
}
else
{
if ((nCurrentX + i) % 4 == 3 || (nCurrentX + i) % 4 == 0)
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 8 * 16 + nCurrentPiece;
}
else
{
pColor[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = 7 * 16 + nCurrentPiece;
}
}
pBuffer[(nCurrentY + j) * nScreenWidth + (nCurrentX + i)] = L'▓';
}
}
}
Block(pBuffer,pColor,nNextPiece,26,8);
if (nScore >= nScoreComp)
{
nScorePosX--;
nScoreComp *= 10;
}
Text(pBuffer,to_wstring(nScore),nScorePosX,2);
if (nLine >= nLineComp)
{
nLinePosX--;
nLineComp *= 10;
}
Text(pBuffer,to_wstring(nLine),nLinePosX,5);
if (!vLines.empty())
{
WriteConsoleOutputCharacter(hConsole,pBuffer,nScreenWidth * nScreenHeight,{ 0,0 },&dwBytesWritten);
Sleep(400);
for (int l = 0; l < vLines.size(); l++)
{
for (int i = 1; i < nBoardWidth - 1; i++)
{
for (int j = vLines.at(l); j > 0; j--)
{
if (j % 2 == 0)
{
if (i % 4 == 1 || i % 4 == 2)
{
pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] - 16;
}
else
{
pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] + 16;
}
}
else
{
if (i % 4 == 1 || i % 4 == 2)
{
pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] + 16;
}
else
{
pColor[j * nScreenWidth + i] = pColor[(j - 1) * nScreenWidth + i] - 16;
}
}
pMatrix[j * nBoardWidth + i] = pMatrix[(j - 1) * nBoardWidth + i];
}
pMatrix[i] = 0;
}
}
vLines.clear();
}
for (int i = 0; i < nScreenWidth; i++)
{
for (int j = 0; j < nScreenHeight; j++)
{
COORD cPos;
cPos.X = i;
cPos.Y = j;
WriteConsoleOutputAttribute(hConsole,&pColor[j * nScreenWidth + i],1,cPos,&dwBytesWritten);
}
}
WriteConsoleOutputCharacter(hConsole,&dwBytesWritten);
}
CloseHandle(hConsole);
cout << "Game Over !" << "\n";
cout << "Score: " << nScore << "\n";
return 0;
}
我使用Visual Studio Code,但在运行时没有错误:
.\test.cpp: In function 'int main()':
.\test.cpp:550:42: error: cannot convert 'wchar_t*' to 'LPCSTR' {aka 'const char*'}
WriteConsoleOutputCharacter(hConsole,&dwBytesWritten);
^~~~~~~
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/x86_64-w64-mingw32/include/Windows.h:74,from .\test.cpp:5:
C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/x86_64-w64-mingw32/include/wincon.h:220:87: note: initializing argument 2 of 'WINBOOL WriteConsoleOutputCharacterA(HANDLE,LPCSTR,DWORD,COORD,LPDWORD)'
WINBASEAPI WINBOOL WINAPI WriteConsoleOutputCharacterA(HANDLE hConsoleOutput,LPCSTR lpCharacter,DWORD nLength,COORD dwWriteCoord,LPDWORD lpNumberOfCharsWritten);
~~~~~~~^~~~~~~~~~~
.\test.cpp:599:41: error: cannot convert 'wchar_t*' to 'LPCSTR' {aka 'const char*'}
WriteConsoleOutputCharacter(hConsole,&dwBytesWritten);
^~~~~~~
In file included from C:/Program Files/mingw-w64/x86_64-8.1.0-posix-seh-rt_v6-rev0/mingw64/x86_64-w64-mingw32/include/Windows.h:74,LPDWORD lpNumberOfCharsWritten);
~~~~~~~^~~~~~~~~~~
似乎有一些与MinGW相关的错误。我一直在检查与该错误有关的某些主题,也许UNICODE与之相关。通常,我发现大多数人都使用旧的MinGW 2017,与该版本相比,它没有任何重大变化。我使用的UNICODE文件属性为UTF-8,系统的PATH,G ++ / GCC的目录都没有问题。 因为我是这些系统背后的编码和机制的新手,所以对此的任何解释和解决方案将不胜感激。
解决方法
好吧,我看到pBuffer存在一些问题,这可能是因为您使用的是多字节字符集。我使用多字节字符集编译了此代码,并且遇到了类似的错误,例如您需要将多字节字符集更改为“使用Unicode字符集”,因此应该解决你的问题。它的工作室选项:)