Win32的:位图实例化最新功能 [英] Win32: Bitmap Instantiation Breaking Function

查看:164
本文介绍了Win32的:位图实例化最新功能的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有我的位图(这是一个spritesheet)之一,这个奇怪的问题。我的游戏完美运行,但GameStart功能,初始化位图和放大器;精灵,休息,如果我取消注释该行code的:

I'm having this strange issue with one of my bitmaps (it's a spritesheet). My game runs perfectly, but the GameStart function, which initializes bitmaps & sprites, breaks if I uncomment this line of code:

g_pPowerup100Bitmap = new Bitmap(hDC, IDB_POWERUP_100, g_hInstance);

其结果是,在函数只是退出当它击中该行code,但GamePaint()一定是所谓的,因为位图位块传输到屏幕上。我知道这个功能是不是正确执行,因为他们不是精灵 - 只是图像(和音乐是不会初始化)。精灵&放大器;音乐初始化是在相同功能的位图初始化以下

The result is that the function just quits when it hits that line of code, but GamePaint() must be getting called because the bitmaps are blitted to the screen. I know the function isn't executing correctly because they're not sprites - just images (and the music never initializes). The sprite & music initialization are below the bitmap initialization in the same function.

什么是更令人沮丧的是,游戏其实作品...有时。然后我就可以适当地和放玩游戏;看到新的动画精灵。尝试调试的东西几十次,但之后,它根本不正确地构建了。

What's even more frustrating is that the game actually works...sometimes. I can then play the game properly & see the new animated sprite. After attempting to debug the thing dozens of times, however, it simply doesn't build properly anymore.

我已经试过:

What I've tried:

1) Try/catch of entire GameStart() contents. Exception is not thrown
2) Extensive breakpoint checking - it's definitely this line
3) Spell-checking variable name - exact same as in header file
4) Re-saving bitmap as 24-bit RGB instead of 32-bit
5) Cleaning & rebuilding both the solution & project file
6) Restarting Visual C++ 2008

位图是64x1536。那是一个问题吗?我的RAM和分类的GTX 570 8GB。这里是整个函数:

The bitmap is 64x1536. Is that a problem? I have 8GB of RAM and a GTX 570 Classified. Here is the entire function:

void GameStart(HWND hWindow)
{
    try
  {
    // Initialize global variables
    g_iInputDelay = 0;
    g_iNumLives = 3;
    g_iScore = 0;
    g_iGameState = 1;
    g_iDifficulty = 1;

    // Seed the random number generator
    srand(GetTickCount());

    // Create the offscreen device context and bitmap
    g_hOffscreenDC = CreateCompatibleDC(GetDC(hWindow));
    g_hOffscreenBitmap = CreateCompatibleBitmap(GetDC(hWindow),
    g_pGame->GetWidth(), g_pGame->GetHeight());
    SelectObject(g_hOffscreenDC, g_hOffscreenBitmap);

    // Create and load the bitmaps
    HDC hDC = GetDC(hWindow);
    g_pHighwayBitmap = new Bitmap(hDC, IDB_HIGHWAY, g_hInstance);
    g_pChickenBitmap = new Bitmap(hDC, IDB_CHICKEN, g_hInstance);
    g_pCarBitmaps[0] = new Bitmap(hDC, IDB_CAR1, g_hInstance);
    g_pCarBitmaps[1] = new Bitmap(hDC, IDB_CAR2, g_hInstance);
    g_pCarBitmaps[2] = new Bitmap(hDC, IDB_CAR3, g_hInstance);
    g_pCarBitmaps[3] = new Bitmap(hDC, IDB_CAR4, g_hInstance);
    g_pChickenHeadBitmap = new Bitmap(hDC, IDB_CHICKENHEAD, g_hInstance);
    g_pMainMenuBitmap = new Bitmap(hDC, IDB_MAIN_MENU, g_hInstance);
    g_pHighScoresMenuBitmap = new Bitmap(hDC, IDB_HIGH_SCORES_MENU, g_hInstance);
    g_pGameOverMenuBitmap =  new Bitmap(hDC, IDB_GAME_OVER_MENU, g_hInstance);
    g_pNormalModeBtnBitmap = new Bitmap(hDC, IDB_NORMAL_MODE_BTN, g_hInstance);
    g_pHardModeBtnBitmap = new Bitmap(hDC, IDB_HARD_MODE_BTN, g_hInstance);
    g_pHighScoresBtnBitmap = new Bitmap(hDC, IDB_HIGH_SCORES_BTN, g_hInstance);
    g_pReplayBtnBitmap = new Bitmap(hDC, IDB_REPLAY_BTN, g_hInstance);
    g_pMainMenuBtnBitmap = new Bitmap(hDC, IDB_MAIN_MENU_BTN, g_hInstance);
    g_pPowerup100Bitmap = new Bitmap(hDC, IDB_POWERUP_100, g_hInstance);

    RECT    rcBounds = { 0, 0, 465, 400 };

    //Button Sprites - Main Menu
    Sprite* pBtnSprite = new Sprite(g_pNormalModeBtnBitmap, 77,228, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(0);
    g_pGame->AddSprite(pBtnSprite, 1);

    pBtnSprite = new Sprite(g_pHardModeBtnBitmap, 254,228, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(0);
    g_pGame->AddSprite(pBtnSprite, 1);

    pBtnSprite = new Sprite(g_pHighScoresBtnBitmap, 166,310, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(3);
    g_pGame->AddSprite(pBtnSprite, 1);


    //Button Sprites - Game Over Menu
    pBtnSprite = new Sprite(g_pReplayBtnBitmap, 167,249, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(0);
    g_pGame->AddSprite(pBtnSprite, 2);

    pBtnSprite = new Sprite(g_pMainMenuBtnBitmap, 82,332, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(1);
    g_pGame->AddSprite(pBtnSprite, 2);

    pBtnSprite = new Sprite(g_pHighScoresBtnBitmap, 252,332, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(3);
    g_pGame->AddSprite(pBtnSprite, 2);

    //Button Sprites - High Scores Menu
    pBtnSprite = new Sprite(g_pMainMenuBtnBitmap, 166,332, 0,0, 1, rcBounds, BA_STOP);
    pBtnSprite->SetStateChange(1);
    g_pGame->AddSprite(pBtnSprite, 3);

        // Create the chicken and car sprites
    g_pChickenSprite = new Sprite(g_pChickenBitmap, rcBounds, BA_STOP);
    g_pChickenSprite->SetPosition(4, 175);
    g_pChickenSprite->SetVelocity(0, 0);
    g_pChickenSprite->SetZOrder(1);
    g_pChickenSprite->SetNumFrames(2);
    g_pChickenSprite->SetAsInputControlled(); //stops auto-frame update
    //DEBUGGING ONLY!!!!!
    g_pChickenSprite->SetID(1);
    g_pGame->AddSprite(g_pChickenSprite, 0);

    Sprite* pSprite = new Sprite(g_pCarBitmaps[0], rcBounds, BA_WRAP);
    pSprite->SetPosition(70, 0);
    pSprite->SetVelocity(0, 6);
    pSprite->SetZOrder(2);
    g_pGame->AddSprite(pSprite, 0);
    pSprite = new Sprite(g_pCarBitmaps[1], rcBounds, BA_WRAP);
    pSprite->SetPosition(160, 0);
    pSprite->SetVelocity(0, 2);
    pSprite->SetZOrder(2);
    g_pGame->AddSprite(pSprite, 0);
    pSprite = new Sprite(g_pCarBitmaps[2], rcBounds, BA_WRAP);
    pSprite->SetPosition(239, 400);
    pSprite->SetVelocity(0, -4);
    pSprite->SetZOrder(2);
    g_pGame->AddSprite(pSprite, 0);
    pSprite = new Sprite(g_pCarBitmaps[3], rcBounds, BA_WRAP);
    pSprite->SetPosition(329, 400);
    pSprite->SetVelocity(0, -9);
    pSprite->SetZOrder(2);
    g_pGame->AddSprite(pSprite, 0);

    // Load the background music
    g_pGame->PlayMIDISong(TEXT("Music.mid"));

    getHighScores(scoreData, g_scoreTop);

    scoreData.close();

  }
  catch (int e)
  {
    cout << "An exception occurred. Exception Nr. " << e << endl;
    system("PAUSE");
  }
}

GameStart()被调用在这方面:

GameStart() is called in this context:

switch (msg)
  {
    case WM_CREATE:
      // Set the game window and start the game
      SetWindow(hWindow);
      GameStart(hWindow);
      return 0;

如果任何人都可以解释为什么该位图查杀功能的一些情况,我将不胜感激!

If anyone could shed some light on why that bitmap is killing the function, I would be very grateful!

修改:汉斯击中右侧问题的头 - 我打勾说,Win32异常复选框和放大器;出现这一行code的内存访问错误:

EDIT: Hans hit the problem right on the head - I ticked that "Win32 Exceptions" checkbox & the memory access error appeared for this line of code:

    CopyMemory(pBitmapBits, pTempBits, pBitmapInfo->bmiHeader.biSizeImage);

时的图像是否太大?我会继续调查,但是任何建议,欢迎。

Is the image too large? I'll keep investigating, but any suggestions are welcome.

推荐答案

不要使用WM_CREATE消息来初始化你的游戏。当您运行64位操作系统,可能会导致SEH异常(如访问冲突),当他们在邮件处理code提高到得到吞噬在32位code有一个很具体的问题。 WM_CREATE是指具有该问题的消息之一。细节很多有关此问题的<一个href=\"http://stackoverflow.com/questions/4933958/vs2010-does-not-show-unhandled-exception-message-in-a-winforms-application-on-a/4934010#4934010\">this回答时,尽管这是非常具体的Winforms中。当你写在C或C ++ code完全相同的问题却存在。

Don't use the WM_CREATE message to initialize your game. There is a very specific problem when you run 32-bit code on a 64-bit operating system that can cause SEH exceptions (like an access violation) to get swallowed when they are raised in the message handling code. WM_CREATE is one of the messages that exhibits the problem. Lots of details about this behavior in this answer, albeit that it is very specific to Winforms. The exact same problem however exists when you write code in C or C++.

有没有(通常)任何需要使用WM_CREATE初始化的东西,你还不如在CreateWindowsEx()调用后移动,因为你只应该需要的窗口句柄。现在调试器将是有益的再次和显示您的code崩溃。

There isn't (usually) any need to use WM_CREATE to initialize stuff, you might as well move it after the CreateWindowsEx() call since you should only need the window handle. The debugger is now going to be helpful again and show you where your code crashes.

如果你真的需要它WM_CREATE然后使用调试+异常调试​​它,勾选为Win32异常的抛出该异常复选框。也顺便来验证这个答案是正确的。

If you really do need it in WM_CREATE then debug it by using Debug + Exceptions, tick the Thrown checkbox for Win32 exceptions. Also the way to verify that this answer is accurate.

这篇关于Win32的:位图实例化最新功能的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆