SDL C程序冻结在sdl_blitsurface上

时间:2013-06-18 19:06:20

标签: sdl freeze surface blit

我正在处理我正在处理的程序的问题。偶尔,它会冻结。没有错误或任何东西。

游戏是一款多人游戏,你可以在那里驾驶一艘船。其他玩家和通电的图片根据您的位置移入和移出视图。在大多数情况下,它运作良好,但在某些情况下,它会锁定。

我已将它追踪到将一个表面涂在另一个表面上的时间。 (SDL_BlitSurface)。

如果我注释掉它所在的单行代码(SDL_BlitSurface),并用简单的圆圈替换图形,它在任何情况下都不会冻结。但是,注释掉圆圈并再次用图形替换它,它会随机冻结。令人沮丧的是,有时它会,有时它不会。有时图形会在屏幕上停留片刻然后冻结,有时它会在它出现的那一刻冻结。有时,它根本不会冻结。我根本无法追踪到任何特别的东西。

我有足够的代码来检查NULL表面,但它似乎没有阻止它。 我还将它设置为将所有图形的信息输出到文件(例如宽度,高度,内存中的位置,x,y等),并且看起来没有任何异常。

我的主要问题是,表面会导致SDL_BlitSurface冻结吗?我可以为表面添加哪些其他检查以确保它不会尝试对坏表面进行blit?

代码太长,无法列出,但以下是它的工作原理:

class Player
{
    Player();

    int x;
    int y;
    int xvel;
    int yvel;
    SDL_Surface *DrawScreen;
    SDL_Surface *ShipPic;

    void check_player_dist();
    void check_powerup_dist();
    void update();
};    

class PowerUp
{
    int x;
    int y;
    int type;
    SDL_Surface *Powerup_Pic;
};

Player::Player()
{
    Apply_Surface(0, 0, PlayerShipPics, ShipPic);
}

Player::Update(Player p[], PowerUp pu[])
{
    x += xvel;
    y += yvel;

    for (int i = 0; i < Num_Players; i++)
    {
        if (check_on_screen(p[i].x, p[i].y) == true)
        {
            Apply_Surface(x - p[i].x, y - p[i].y, p[i].ShipPic, DrawScreen);
        }
    }

    for (int i = 0; i < Num_PowerUps; i++)
    {
        if (check_on_screen(pu[i].x, pu[i].y) == true)
        {
            Apply_Surface(x - pu[i].x, y - pu[i].y, pu[i].Pic, DrawScreen);
        }
    }
}


int main()
{
    SDL_Surface *Screen;
    Player players[4];
    PowerUp powerups[200];
    Num_Players = 4;
    Num_PowerUps = 200;

    while (quit == false)
    {
        for (int i = 0; i < Num_Players; i++)
        {
            players[i].update(players, powerups);
            switch (i)
            {
                case 0: ScreenX = 0; ScreenY = 0; break;
                case 1: ScreenX = ScreenWid / 2; ScreenY = 0; break;
                case 2: ScreenX = 0; ScreenY = ScreenHigh / 2; break;
                case 3: ScreenX = ScreenWid / 2; ScreenY = ScreenHigh / 2; break;
            }
            Apply_Surface (ScreenX, ScreenY, players[i].DrawScreen, Screen);
        }

        if (SDL_Flip(Screen) == -1)
        {
            return -1;
        }
    }
}

void Apply_Surface (int x, int y, SDL_Surface* Source, SDL_Surface* Destination, SDL_Rect* Clip)
{
    SDL_Rect Offset;

    Offset.x = x;
    Offset.y = y;

    if ((Source != NULL) && (Destination != NULL))
    {
        SDL_BlitSurface (Source, Clip, Destination, &Offset );
    }
}

我注意到当两个或更多玩家彼此靠近并且它试图在两个屏幕上绘制相同的电源时它通常会冻结。但是再次......并非总是如此!

2 个答案:

答案 0 :(得分:1)

好吧,我弄清楚它是什么。

我正在使用SDL_GFX库以及我的游戏。许多图像是使用rotozoomSurface()创建的,它是SDL_GFX的函数。

原来有一个错误,在某些情况下,我不知道,它会创造一个“大部分”时间都可以工作的坏表面,但在正确的条件下会崩溃。例如,放置在特定的x&amp; y坐标在屏幕上。 (不确定)。旋转/缩放的图像大约可以在95%的时间内工作,因此很难确定问题所在。

当创建图像时,解决方法是在受控条件下将SDL_BlitSurface()放到另一个表面上,例如将其放在坐标(0,0)处。然后,删除旋转和缩放的表面,并使用新的“安全”表面。

之后效果很好。

希望这可以帮助任何使用SDL_GFX但无法弄清楚程序崩溃原因的人。

示例:

在:

SDL_Surface *original = SDL_CreateRGBSurface(SDL_SWSURFACE, Ship_Width, Ship_Height, Screen_BPP, 0, 0, 0, 0);
Apply_Surface(0, 0, ShipsPic, original, &bounds);

SDL_Surface *finished = rotozoomSurface(original, pic_angle, zoom, SMOOTHING_ON);
SDL_FreeSurface(original);
return finished;

之后(固定):

SDL_Surface *original = SDL_CreateRGBSurface(SDL_SWSURFACE, Ship_Width, Ship_Height, Screen_BPP, 0, 0, 0, 0);
Apply_Surface(0, 0, ShipsPic, original, &bounds);

SDL_Surface *temp = rotozoomSurface(original, pic_angle, zoom, SMOOTHING_ON);
SDL_Surface *finished = SDL_CreateRGBSurface(SDL_SWSURFACE, temp->w, temp->h, Screen_BPP, 0, 0, 0, 0);

Apply_Surface(0, 0, temp, finished);
SDL_FreeSurface(temp);
SDL_FreeSurface(original);
return finished;

为了它的价值,Apply_Surface()函数:

void Apply_Surface (int x, int y, SDL_Surface* Source, SDL_Surface* Destination, SDL_Rect* Clip)
{
    SDL_Rect Offset;

    Offset.x = x;
    Offset.y = y;

    if ((Source != NULL) && (Destination != NULL))
    {
        SDL_BlitSurface (Source, Clip, Destination, &Offset );
    }
}

答案 1 :(得分:0)

没有足够的信息来确定究竟发生了什么。计算机不喜欢“有时”做事,他们要么做或不做,所以这让我相信可能有一些变量正在做一些不应该做的事情。

以防万一,您的Apply_Surface()函数是什么样的?我认为那是你正在进行实际操作的地方,如果那是你遇到问题的地方,那对我们这些试图找出你的困境的人来说是有用的。