gpt4 book ai didi

c++ - 类和 Windows DC (C++) 中的奇怪数组行为?

转载 作者:行者123 更新时间:2023-12-02 10:52:12 25 4
gpt4 key购买 nike

我正在创建一个基于文本的 Windows 游戏,但我遇到了一个问题(我猜):数组在类作用域内的工作方式与在主函数内的工作方式不同。据我所知,这是较大的数组类成员(或大量变量)与创建 DC 或其他 Windows API 调用和/或变量的 Windows 之间的某种交互。

我想要做的是有一个名为 Map 的类,其中包含二维 Tiles 数组。 Tile 只是一个包含基本 Tile 信息的简单结构。我想将数组设置为 256 x 256。据我所知,这应该不是问题。每个 Tile 应为 32 字节。该数组总共有 2 MB。

但是,当我在主函数中声明 Map 类的变量,然后使用 Windows DC 进行操作时,游戏崩溃了。返回值似乎有所不同,在当前形式中,它通常返回 255,但我也得到了“进程终止状态 -1073741571”。不过,128 x 128 数组确实可以在类中使用。如果我删除 DisplayScreen 中的数组或代码,它也可以正常工作。正如我所暗示的,如果我只是将 Tiles 数组移至主函数,它也可以工作。

说实话,我很困惑。我不知道有什么区别。一切都不会超出范围。无论是公共(public)成员还是私有(private)成员都没有关系。非动态类成员都应该在堆栈上声明,并且它在类中与其他情况下的工作方式不应该有任何不同,对吗?

有关其他信息,我将 Code::Blocks 与 Min GW 编译器一起使用。一切都是最新的。我运行的是 Windows 10。我的计算机规范也不应该成为问题,但如果重要的话,我有 16 GB 内存和 4Ghz Athlon FX 8 核心处理器。

编辑:这是完整的代码,因此没有遗漏任何内容

Game.h:

#ifndef GAME_H_INCLUDED
#define GAME_H_INCLUDED

struct Tile
{
char chr[2];
int r[2], b[2], g[2];

bool solid;
bool translucent;
int opacity;
};

class Map
{
Tile tileMap[256][256];

public:
Map();

};

Map::Map()
{
int i, j;

for(i=0;i<256;i++)
{
for(j=0;j<256;j++)
{
tileMap[i][j].chr[0] = 'X';
tileMap[i][j].b[0] = 255;
tileMap[i][j].r[0] = 255;
tileMap[i][j].g[0] = 255;

tileMap[i][j].chr[1] = ' ';
tileMap[i][j].b[1] = 0;
tileMap[i][j].r[1] = 0;
tileMap[i][j].g[1] = 0;

tileMap[i][j].solid = false;
tileMap[i][j].translucent = false;
tileMap[i][j].opacity = 255;
}
}
}

ma​​in.cpp:

#include <windows.h>
#include "Game.h"

#define FRAMERATE 60

//Function declarations
LRESULT CALLBACK WindowProcedure (HWND, UINT, WPARAM, LPARAM);
void DisplayScreen(HWND pWnd, Map &pMap);

//Make the class name into a global variable
char strClassName[ ] = "GameApp";

int WINAPI WinMain (HINSTANCE hThisInstance,
HINSTANCE hPrevInstance,
LPSTR lpstrArgument,
int nCmdShow)
{
HWND hWnd; //This is the handle for our window
MSG messages; //Here messages to the application are saved
WNDCLASSEX wndClassEx; //Data structure for the windowclass

Map test;

DWORD sysTimer;
DWORD sysPrevTime = 0;
DWORD timerDelta = 1000 / FRAMERATE;

//Get a handle for the whole screen
HDC hDC = GetDC(NULL);

//Initalize the Window structure
wndClassEx.hInstance = hThisInstance;
wndClassEx.lpszClassName = strClassName;
wndClassEx.lpfnWndProc = WindowProcedure;
wndClassEx.style = CS_DBLCLKS;
wndClassEx.cbSize = sizeof (WNDCLASSEX);
wndClassEx.hIcon = LoadIcon (NULL, IDI_APPLICATION);
wndClassEx.hIconSm = LoadIcon (NULL, IDI_APPLICATION);
wndClassEx.hCursor = LoadCursor (NULL, IDC_ARROW);
wndClassEx.lpszMenuName = NULL; //No menu
wndClassEx.cbClsExtra = 0;
wndClassEx.cbWndExtra = 0;
wndClassEx.hbrBackground = CreateSolidBrush(RGB(0,0,0));

//Register the window class, and if it fails quit the program
if (!RegisterClassEx (&wndClassEx))
return 0;

//Create Window with registered window class
hWnd = CreateWindowEx (
0,
strClassName, //Class name
"Game Test", //Title Text
WS_OVERLAPPEDWINDOW, //default window type
0, //X pos of window at top left
0, //Y pos of window at top left
GetDeviceCaps(hDC, HORZRES), //Set window width to screen width
GetDeviceCaps(hDC, VERTRES), //Set window height to screen height
HWND_DESKTOP, //Child-window to desktop
NULL, //No menu
hThisInstance, //Program Instance handler
NULL); //No Window Creation data


//Removes borders from the window
SetWindowLong(hWnd, GWL_STYLE, WS_POPUP);
//Make the window visible on the screen
ShowWindow (hWnd, nCmdShow);

//Run the message and game loop
while (true)
{
while(PeekMessage(&messages,NULL,0,0, PM_REMOVE))
{
if (messages.message == WM_QUIT)
{
ReleaseDC(NULL, hDC);
DestroyWindow(hWnd);
return 0;
}

TranslateMessage(&messages);
DispatchMessage(&messages);
}

sysTimer = timeGetTime();

if (sysTimer >= (sysPrevTime + timerDelta) )
{
sysPrevTime = sysTimer;
DisplayScreen(hWnd, test);
}

}
}

//This function is called by the Windows function DispatchMessage()
LRESULT CALLBACK WindowProcedure (HWND hWnd, UINT message, WPARAM wParam, LPARAM lParam)
{
switch (message)
{
case WM_DESTROY:
PostQuitMessage (0); //Send WM_QUIT to the message queue
break;

default:
return DefWindowProc (hWnd, message, wParam, lParam);
}

return 0;
}

void DisplayScreen(HWND pWnd, Map &pMap)
{
HDC hDC = GetWindowDC(pWnd);
HDC hdcBuf = CreateCompatibleDC(hDC);

HBITMAP hbmBuf = CreateCompatibleBitmap(hDC, 800, 600);
HFONT hMapFont = CreateFont(17,11,0,0,400,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH | FF_MODERN,"Lucida Console");
HFONT hTxtFont = CreateFont(17,11,0,0,400,FALSE,FALSE,FALSE,ANSI_CHARSET,OUT_DEFAULT_PRECIS,CLIP_DEFAULT_PRECIS,ANTIALIASED_QUALITY,DEFAULT_PITCH | FF_MODERN,"Lucida Console");

SelectObject(hdcBuf, hbmBuf);
SelectObject(hdcBuf, hMapFont);

SetBkColor(hdcBuf, RGB(0,0,0));
SetTextColor(hdcBuf, RGB(255,255,255));

//Draw to the buffer
TextOut(hdcBuf, 10, 10, "Hello World @", 15);

//Tranfers the buffer to the Screen
BitBlt(hDC, 100, 100, 800, 600, hdcBuf, 0, 0, SRCCOPY);

//Release all object handles
DeleteObject(hTxtFont);
DeleteObject(hMapFont);
DeleteObject(hbmBuf);

DeleteDC(hdcBuf);
ReleaseDC(pWnd, hDC);
}

即使只有一个创建 DC 的实例,它也会崩溃。它工作得很好,否则即使我将其放置一个小时,也会一遍又一遍地创建和销毁 DC 并显示位图。一旦我创建了包含大数组的类,它就会死掉。

我实际上曾经将 Display 函数作为类函数,然后将其移出,因为我认为这是问题所在,但事实并非如此。

有趣的是,如果我更改“Map test;”的声明到“ map *测试=新 map ;”并适当更改程序的其余部分,它可以工作。但老实说,这样做似乎有点愚蠢,而且我认为如果我没有充分的理由将所有内容都放在堆上,这会减慢一切。另外,我不喜欢绷带。如果有问题,我宁愿修复它。

有什么想法吗?

最佳答案

您遇到了堆栈溢出(情况,而不是网站)。

关于c++ - 类和 Windows DC (C++) 中的奇怪数组行为?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/39924223/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com