簡體   English   中英

Win32:位圖實例化中斷函數

[英]Win32: Bitmap Instantiation Breaking Function

我的一個位圖(這是一個spritesheet)我遇到了這個奇怪的問題。 我的游戲運行得很好,但GameStart函數初始化位圖和sprite,如果我取消注釋這行代碼就會中斷:

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

結果是函數只是在它到達那行代碼時退出 ,但是必須調用GamePaint()因為位圖被blit到屏幕上。 我知道函數沒有正確執行,因為它們不是精靈 - 只是圖像(音樂永遠不會初始化)。 精靈和音樂初始化在同一功能中的位圖初始化之下。

更令人沮喪的是,游戲確實有效......有時候 然后我可以正確地玩游戲並看到新的動畫精靈。 然而,在試圖調試這個東西幾十次之后,它根本就沒有正確構建。

我嘗試過的:

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。 那是問題嗎? 我有8GB的RAM和GTX 570分類。 這是整個功能:

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():

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

如果有人能夠解釋為什么該位圖正在殺死該函數,我將非常感激!

編輯 :Hans正好問題 - 我勾選了“Win32 Exceptions”復選框以及此代碼行出現的內存訪問錯誤:

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

圖像太大了嗎? 我會繼續調查,但歡迎任何建議。

不要使用WM_CREATE消息初始化您的游戲。 當您在64位操作系統上運行32位代碼時會出現一個非常具體的問題,這可能導致在消息處理代碼中引發SEH異常(如訪問沖突)時被吞下。 WM_CREATE是顯示問題的消息之一。 這個答案中有很多關於這種行為的細節,盡管它對Winforms非常具體。 但是,當您使用C或C ++編寫代碼時,會出現完全相同的問題。

沒有(通常)需要使用WM_CREATE來初始化東西,你也可以在CreateWindowsEx()調用之后移動它,因為你應該只需要窗口句柄。 調試器現在將再次有用,並向您顯示代碼崩潰的位置。

如果你確實在WM_CREATE中需要它,那么使用Debug + Exceptions調試它,勾選Win32異常的Thrown復選框。 還有驗證這個答案是否准確的方法。

就像我現在一樣,在調用GetDC之后,你必須調用ReleaseDC。 但是你進行了三次GetDC調用。 留下一個電話,存儲HDC,最后發布它。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM