C ++ / SDL中的奇怪行为?

时间:2012-01-30 03:46:01

标签: c++ sdl

我一直在使用C ++ / SDL开发游戏,但是我很困惑为什么我的程序在“while”循环结束之前关闭。我寻找任何漏洞,但空手而归。然而,在试验该程序后,我怀疑罪魁祸首在我的“menu.h”文件中。这是游戏中的所有代码。到目前为止,Player.h只是一堆定义。

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)

2 个答案:

答案 0 :(得分:0)

我怀疑@John钉了它,值得称赞答案。当您开始为clip.level_select[1].x分配值时,您刚刚开始无意中压缩属于其他变量的内存。实际结果可能与编译器有关,但是您不可能以某种方式更改进程中的quit变量。尝试更改变量声明:

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

看看会发生什么。

答案 1 :(得分: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(屏幕)(在“menu.h”中“ menu_action()“)程序在没有冻结的情况下立即关闭而崩溃。