SDL C程序冻结在sdl_blitsurface



我正在开发的一个程序出现了问题。有时候,它会结冰。没有错误或任何东西

这是一款多人游戏,玩家可以驾驶一艘船。其他玩家和道具的图片会根据你的位置出现或消失。在大多数情况下,它工作得很好,但在某些情况下,它会锁定。

我已经追踪到它从一个表面到另一个表面。(SDL_BlitSurface)。

如果我注释掉它位进的单行代码(SDL_BlitSurface),并用一个简单的圆圈替换图形,它在任何情况下都不会冻结。但是,注释掉圆圈并将其替换为图形的位元化,它将随机冻结。令人沮丧的是,有时会,有时不会。有时图形会在屏幕上停留片刻然后冻结,有时它会在显示的那一刻冻结。有时,它根本不会结冰。我就是找不到具体的东西。

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

我的主要问题是,表面会导致SDL_BlitSurface冻结吗?我还可以为表面添加哪些检查,以确保它不会试图损坏坏的表面?

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

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 );
    }
}

我注意到当两个或更多玩家靠近对方时,它通常会冻结,并且它试图在他们的屏幕上绘制相同的能量。但又……不总是!

我知道是什么了。

我在游戏中使用了SDL_GFX库。许多图像是使用SDL_GFX的函数rotozoomSurface()创建的。

结果里面有个bug,在某些我不知道的情况下,它会产生一个糟糕的表面,在"大多数"时间里可以工作,但在适当的条件下,会崩溃。例如,被放置在一个特定的x &屏幕上的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 );
    }
}

没有足够的信息来弄清楚到底发生了什么。计算机不喜欢"有时"做一些事情,它们要么做,要么不做,所以这让我相信可能有一些变量做了一些它不应该做的事情。

以防万一,Apply_Surface()函数是什么样子的?我猜那就是你实际做数据传输的地方,如果那就是你遇到问题的地方,那将对我们这些试图弄清楚你的困境的人很有用。

最新更新