我正在寫什麼應該是俄羅斯方塊遊戲的代碼。它很早就開始了,現在它只顯示一個單一的片斷(這個片斷在那個時候會「下降」),這是它應該做的。向上箭頭允許您通過隨機生成的部分序列(使用「bag」方法)向前循環(特別是僅循環)。並且,使用左右箭頭,您可以旋轉這些部分。無論如何,它是在一個win32平臺上編碼的,我發現在一定數量的幀(運行WM_PAINT)後,主HDC變爲空,一切都停止。按住右箭頭鍵或左箭頭鍵的幀數大約是按住向上箭頭鍵的兩倍。奇怪的是,在大約1000幀後,我正在主動繪製的控制檯區域(600x600像素幀)將變黑(hdc尚未被取消),並且只有當向上箭頭被按下時, hdc無效。我懷疑是問題的是當按下向上箭頭鍵時調用的方法將hdc作爲參數傳遞給類內方法(告訴我這是不好的練習還是應該做的事情)。我認爲HDC可能是腐敗或某事(說實話,我不知道)。左右箭頭鍵不直接調用HDC作爲參數的方法。由於箱子標籤以及win32模板的設計,我必須存儲一個HDC,它的範圍不屬於任何案例標籤,所以我可以訪問窗口的油漆案例外的手柄(我覺得這是一種很差的做法,但我想了解爲什麼在我走出去尋找新的方式之前)。我將發佈代碼,存儲的HDC稱爲mainHDC,它在主要語句之前定義。爲了讓你瞭解代碼結構,我將給出代碼結構的概述:C++ Win32:HDC的和調試
包含基本win32程序的主.cpp文件在WM_PAINT中調用Tetris類的構造函數並將其存儲爲像mainHDC一樣,當提示時,「下一個」方法(帶來下一個片段),「turnPiece」方法(基於參數順時針或逆時針旋轉片)和更新屏幕的「繪畫」方法,重新繪製目前的一塊。在俄羅斯方塊類(它在它自己的頭文件中)中,有一個叫做「pieces」的子類,它包含關於它的對象的信息,這些信息是由另一個級別的子類定義的,這些子類用單個字符命名形狀。片段的形狀,顏色和大小存儲在一個二維指針數組中(使用COLORREF)。 「Pieces」包含自己的「DrawObject」方法,該方法繪製調用它的對象(與所有繪圖/繪畫方法都有HDC作爲參數一樣)。還有一種方法可以旋轉稱爲「turnTet」的形狀(「turnPiece」方法將調用從主.cpp文件中繼到「碎片」)。唯一的其他適用的方法是在「俄羅斯方塊」類中找到的那些「繪畫」和「下一個」(它們最終繪製對象)。 WM_KEY情況(不包括VK_UP情況)不使用保存的hdc,而是使用InvalidateRect()。
這裏的.cpp文件
int tempt = 2;
int tempvar = 0;
tetris *mainOBJ;
HDC mainHDC;
HDC testHDC;
LRESULT CALLBACK WndProc(HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_KEYDOWN:
switch (wParam) {
case VK_LEFT:
mainOBJ->turnPiece(false);
InvalidateRect(hWnd, 0, FALSE);
break;
case VK_RIGHT:
mainOBJ->turnPiece(true);
InvalidateRect(hWnd, 0, FALSE);
break;
case VK_UP:
mainOBJ->next(mainHDC);
InvalidateRect(hWnd, 0, FALSE);
break;
}
break;
case WM_COMMAND:
//Non-applicable & has not been changed
case WM_PAINT:
{
PAINTSTRUCT ps;
HDC hdc = BeginPaint(hWnd, &ps);
mainHDC = hdc;
HPEN oldP;
HPEN newP;
COLORREF qLC;
qLC = RGB(0, 0, 0);
newP = CreatePen(PS_SOLID, 1, qLC);
oldP = (HPEN) SelectObject(hdc, newP);
tempt++;
//USED FOR COUNTING FRAMES WITH DEBUGGER
if (tempt % 1 == 0) {
if (tempvar == 0) {
//CONSTRUCTOR CALL
mainOBJ = new tetris(hdc);
tempvar++;
}
//PAINT METHOD CALL
mainOBJ->paint(hdc);
}
if (hdc == NULL) {
int x = 3;
int y = x + 3; //SET DEBUG_BREAK POINT HERE
}
testHDC = hdc;
SelectObject(hdc, oldP);
DeleteObject(newP);
EndPaint(hWnd, &ps);
}
break;
}
}
頭文件的適用部分,它包含了俄羅斯方塊和片類
class tetris {
public:
class pieces {
private:
COLORREF **test;
int size;
public:
//Abbreviated for space
class O {};
class I {};
class S {};
class Z {};
class T {};
class L {};
class J {};
void setSize(int a) {
//Initializing the piece-array
test = new COLORREF*[a];
size = a;
int i = 0;
while (i < a) {
test[i] = new COLORREF[a];
i++;
}
}
void setShape(COLORREF **shape) {
test = shape;
}
void setColor(HDC hdc, COLORREF rgb) {
HPEN Penn = CreatePen(PS_SOLID, 1, rgb);
HPEN Peno = (HPEN)SelectObject(hdc, Penn);
}
static pieces getObject(char type) {
pieces Gen;
switch (type) {
case 'O':
{
//Identical (almost) to the other cases
O pcs = O();
Gen = *pcs.getObject();
return Gen;
}
break;
case 'I':
case 'S':
case 'Z':
case 'T':
case 'L':
case 'J':
return pieces();
}
void turnTet(bool clockwise) {
int i = 0;
int s;
COLORREF **shape;
int ter = size - 1;
shape = new COLORREF*[2];
while (i < size) {
shape[i] = new COLORREF[2];
s = 0;
while (s < size) {
shape[i][s] = def;
s++;
}
i++;
}
i = 0;
while (i < size) {
s = 0;
while (s < size) {
if (clockwise) {
shape[s][ter - i] = test[i][s];
}
else {
shape[ter - s][i] = test[i][s];
}
s++;
}
i++;
}
test = shape;
}
void drawObject(HDC hWnd) {
int i = 0;
int s;
while (i < size) {
s = 0;
while (s < size) {
setColor(hWnd, test[i][s]);
int scaleOfBox = 90;
DrawBox((s + 1) * scaleOfBox, (i + 1) * scaleOfBox, scaleOfBox - 1, scaleOfBox - 1, hWnd);
s++;
}
i++;
}
}
void DrawBox(int x, int y, int w, int h, HDC hdc) {
if (h < 0) {
h *= -1;
}
if (w < 0) {
w *= -1;
}
int i = 0;
while (i < h) {
MoveToEx(hdc, x, y + i, NULL);
LineTo(hdc, x + w, y + i);
i++;
}
}
};
tetris(HDC hdc) {
refresh();
bagp[cur].drawObject(hdc);
}
void next(HDC hdc) {
bagp[cur].DrawBox(0, 0, 600, 600, hdc);
bagp[cur].drawObject(hdc);
cur++;
if (cur > 6) {
refresh();
}
}
void turnPiece(bool clockwise) {
bagp[cur].turnTet(clockwise);
}
void refresh() {
srand(time(NULL));
bag[0] = rand() % 7;
int i = 1;
while (i < 7) {
bool open = false;
cur = i;
while (!open) {
bag[i] = rand() % 7;
int s = 1;
open = true;
while (s <= i) {
if (bag[i] == bag[i - s]) {
open = false;
}
s++;
}
}
i++;
}
cur = 0;
while (cur < 7) {
switch (bag[cur]) {
case 0:
bagp[cur] = pieces::getObject('O');
break;
case 2:
bagp[cur] = pieces::getObject('T');
break;
case 1:
bagp[cur] = pieces::getObject('I');
break;
case 3:
bagp[cur] = pieces::getObject('S');
break;
case 4:
bagp[cur] = pieces::getObject('Z');
break;
case 5:
bagp[cur] = pieces::getObject('L');
break;
case 6:
bagp[cur] = pieces::getObject('J');
break;
}
cur++;
}
cur = 0;
}
void paint(HDC hdc) {
COLORREF temp = def;
bagp[cur].setColor(hdc, temp);
bagp[cur].DrawBox(0, 0, 600, 600, hdc);
bagp[cur].drawObject(hdc);
}
private:
int bag[7];
int cur;
pieces bagp[7];
};
我不明白爲什麼HDC勾銷像它。我再次懷疑它與如何將hdc作爲參數傳遞或者我如何保存hdc有關。請幫助...(謝謝)。
太多無關的文字。您的問題與* Tetris *無關。請以最簡潔的方式說明您的問題。 – IInspectable