2012-01-30 51 views
0

我一直在用C++/SDL編寫遊戲,但我很困惑爲什麼我的程序在「while」循環結束之前關閉。我查找了任何漏洞,但空手而出。但是,在對該程序進行實驗之後,我懷疑罪魁禍首是在我的「menu.h」文件中。這裏是遊戲中的所有代碼。 Player.h目前只是一大堆定義。C++/SDL中的奇怪行爲?

include_file.h

#ifndef INCLUDE_FILE_H_INCLUDED 
#define INCLUDE_FILE_H_INCLUDED 

#include <map> 
#include <string> 
#include <SDL/SDL.h> 
#include <SDL/SDL_image.h> 
#include <SDL/SDL_mixer.h> 

using namespace std; 

struct image_struct 
{ 
    SDL_Surface *donkey; 
    SDL_Surface *donkey_select; 

    SDL_Surface *kawasaki; 
    SDL_Surface *kawasaki_select; 

    SDL_Surface *desert; 
    SDL_Surface *desert_select; 
}; 

struct sound_struct 
{ 
    Mix_Music *menu_theme; 
}; 

struct clip_struct 
{ 
    SDL_Rect level_select[1]; 
    SDL_Rect player_select[1]; 
    SDL_Rect bike_select[1]; 
}; 

void applysurface(int x, int y, SDL_Surface *source, SDL_Surface *destination, SDL_Rect *source_clip = NULL) 
{ 
    SDL_Rect offset; 

    offset.x = x; 
    offset.y = y; 

    SDL_BlitSurface(source, source_clip, destination, &offset); 
}; 

int quit; 
string level; 

image_struct image; 
sound_struct sound; 
clip_struct clip; 

SDL_Surface *screen; 
SDL_Event event; 

void variable_setvalue(void) 
{ 
    SDL_Init(SDL_INIT_VIDEO | SDL_INIT_AUDIO); 
    Mix_OpenAudio(22050, MIX_DEFAULT_FORMAT, 2, 4096); 

    clip.level_select[0].x = 0; 
    clip.level_select[0].y = 0; 
    clip.level_select[0].w = 128; 
    clip.level_select[0].h = 128; 

    clip.level_select[1].x = 128; 
    clip.level_select[1].y = 0; 
    clip.level_select[1].w = 256; 
    clip.level_select[1].h = 128; 

    clip.player_select[0].x = 0; 
    clip.player_select[0].y = 0; 
    clip.player_select[0].w = 50; 
    clip.player_select[0].h = 100; 

    clip.player_select[1].x = 50; 
    clip.player_select[1].y = 0; 
    clip.player_select[1].w = 100; 
    clip.player_select[1].h = 100; 

    clip.bike_select[0].x = 0; 
    clip.bike_select[0].y = 0; 
    clip.bike_select[0].w = 100; 
    clip.bike_select[0].h = 50; 

    clip.bike_select[1].x = 0; 
    clip.bike_select[1].y = 50; 
    clip.bike_select[1].w = 100; 
    clip.bike_select[1].h = 100; 

    SDL_Surface *screen = SDL_SetVideoMode(512, 512, 32, SDL_SWSURFACE); 

    image.donkey = IMG_Load("images/donkey.png"); 
    image.donkey_select = IMG_Load("images/donkey_select.png"); 

    image.kawasaki = IMG_Load("images/kawasaki.png"); 
    image.kawasaki_select = IMG_Load("images/kawasaki_select.png"); 

    image.desert = IMG_Load("images/desert.png"); 
    image.desert_select = IMG_Load("images/desert_select.png"); 

    sound.menu_theme = Mix_LoadMUS("sounds/death_desert_racing.wav"); 

    level = "desert"; 
    quit = 0; 

}; 


#endif // INCLUDE_FILE_H_INCLUDED 

的main.cpp

#include "include_file.h" 
#include "player.h" 
#include "menu.h" 

int main(int argc, char *argv[]) 
{ 
    variable_setvalue(); 

    while (quit == 0) 
    { 
     menu_action(); 
     if (level == "desert") 
     { 
      SDL_WM_SetCaption("Death Desert Racing", NULL); 
     }; 
    }; 

    SDL_FreeSurface(screen); 
    Mix_CloseAudio(); 
    SDL_Quit(); 
    return 0; 
}; 

menu.h

#ifndef MENU_H_INCLUDED 
#define MENU_H_INCLUDED 

#include "include_file.h" 
#include "player.h" 

struct menu_struct 
{ 
    int desert_x; 
    int desert_y; 
    int donkey_x; 
    int donkey_y; 
    int kawasaki_x; 
    int kawasaki_y; 

    SDL_Rect *desert; 
    SDL_Rect *donkey; 
    SDL_Rect *kawasaki; 
}; 

menu_struct menu; 

void menu_action(void) 
{ 
    SDL_Event menu_event; 

    string level_select = "desert"; 
    string character_select = "donkey"; 
    string vehical_select = "kawasaki"; 

    menu.desert = &clip.level_select[0]; 
    menu.donkey = &clip.player_select[0]; 
    menu.kawasaki = &clip.bike_select[0]; 

    menu.desert_x = 0; 
    menu.desert_y = 0; 

    menu.donkey_x = 0; 
    menu.donkey_y = 0; 

    menu.kawasaki_x = 0; 
    menu.kawasaki_y = 0; 

    int menu_number = 0; 
    int done = 0; 

    int x = 0; 
    int y = 0; 

    while (done == 0) 
    { 
     while (menu_number == 0) 
     { 
      if(SDL_PollEvent(&menu_event)) 
      { 
       x = menu_event.motion.x; 
       y = menu_event.motion.y; 

       switch(menu_event.type) 
       { 
        case SDL_MOUSEMOTION: 
         if ((x > menu.desert_x) and (x < menu.desert_x + 128) and (y > menu.desert_y) and (y < menu.desert_y + 128)) 
         {menu.desert = &clip.level_select[1];} 
         else {menu.desert = &clip.level_select[0];}; 
         break; 
       }; 
      }; 

    applysurface(menu.desert_x,menu.desert_y,image.desert_select,screen,menu.desert); 
    SDL_Flip(screen); 
    }; 
     while (menu_number == 1) 
     { 
      if(SDL_PollEvent(&menu_event)) 
      { 
       x = menu_event.motion.x; 
       y = menu_event.motion.y; 

       switch(menu_event.type) 
       { 
        case SDL_MOUSEMOTION: 
         if ((x > menu.donkey_x) and (x < menu.donkey_x + 128) and (y > menu.donkey_y) and (y < menu.donkey_y + 128)) 
         {menu.donkey = &clip.player_select[1];} 
         else {menu.donkey = &clip.player_select[0];}; 
         break; 
       }; 


      applysurface(menu.donkey_x,menu.donkey_y,image.donkey,screen,menu.donkey); 
      SDL_Flip(screen); 
      }; 
     }; 
    }; 
}; 

#endif // MENU_H_INCLUDED 

編輯:我通過調試步驟之後接收到這些消息。

#0 6812A21B SDL_Flip() (e:\projects\death_desert_racing\bin\debug\SDL.dll:??) 
#1 00401748 menu_action() (E:/Projects/Death_Desert_Racing/menu.h:69) 
#2 004019BD SDL_main(argc=1, argv=0x9e0750) (E:\Projects\Death_Desert_Racing\main.cpp:11) 
#3 00402887 console_main(argc=1, argv=0x9e0750) (./src/main/win32/SDL_win32_main.c:315) 
#4 00402944 WinMain(hInst=0x400000, hPrev=0x0, szCmdLine=0x241f22 "", sw=10) (./src/main/win32/SDL_win32_main.c:398) 
#5 0040205A main(argc=1746172080, argv=0x68134e90, __p__environ=0x68134540 <SDL_RegisterApp+15408>) (../mingw/main.c:73) 
+0

爲什麼你認爲罪魁禍首駐留在'menu.h'中?你對問題的調查揭示了什麼?您是否使用了調試器並逐步完成並嘗試調試? – 2012-01-30 03:48:59

+0

我在main.cpp的「menu_action」之前放置了「SDL_WM_SetCaption」,它在窗口關閉之前顯示了標題。我速度很快,看到標題從「SDL_APP」更改爲「death_desert_racing」。我刪除了帖子中的代碼行。 – Ripspace 2012-01-30 03:54:42

+3

您是否試過在調試器中單步執行代碼?它將幫助您確定問題的出現位置,甚至可能會告訴您究竟會出現什麼問題。從我觀察到的: – 2012-01-30 06:40:42

回答

0

我知道我在回答我自己的問題,但我最終發現了它!所以我使用了Joachim關於通過調試器的步驟的提示,然後它說有一個錯誤說: 「程序接收到的信號SIGSEGV,分段錯誤。」所以,我查了一下這個意思,在www.unix.com/programming/27967-program-received-signal-sigsegv-segmentation-fault.html。所以我仔細研究了SDL_Surface屏幕的聲明和賦值。原來,在「include_file.h」裏,在variable_setvalue()裏面,我不小心把「SDL_Surface *」放在屏幕前,這意味着我第一次使用SDL_Flip(screen)(它在「menu.h」 menu_action()「)程序通過立即關閉而不會凍結而崩潰。

+0

我不知道如何建立鏈接,所以現在鏈接不可用。 – Ripspace 2012-01-31 04:53:17

0

我懷疑@約翰釘住了它,值得信任的答案。當您開始將值分配給clip.level_select[1].x時,您剛剛開始無意中壓縮屬於其他變量的內存。實際的結果可能與編譯器有關,但不知怎的,你在某個過程中改變了quit變量。嘗試更改變量聲明:

struct clip_struct 
{ 
    SDL_Rect level_select[2]; 
    SDL_Rect player_select[2]; 
    SDL_Rect bike_select[2]; 
}; 

然後看看會發生什麼。

+0

發生同樣的事情。絕對沒有任何變化。我嚴重懷疑問題出在menu.h文件中。 – Ripspace 2012-01-31 00:32:08

+0

但是,這可能是另一個尚未出現的問題。 – John 2012-01-31 10:26:42