Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/angular/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
SDL C程序在SDL_blitsurface上冻结_Sdl_Freeze_Surface_Blit - Fatal编程技术网

SDL C程序在SDL_blitsurface上冻结

SDL C程序在SDL_blitsurface上冻结,sdl,freeze,surface,blit,Sdl,Freeze,Surface,Blit,我正在做的一个程序有问题。偶尔,它会结冰。没有错误或任何东西 这个游戏是一个多人游戏,你可以驾驶一艘船四处飞行。其他玩家和电源的图片根据您的位置移入和移出视图。在大多数情况下,它工作得很好,但在某些情况下,它会锁定 我一直追踪到它在一个表面撞击另一个表面。(SDL_BlitSurface) 如果我注释掉它所在的单行代码(SDL_BlitSurface),并用一个简单的圆圈替换图形,它在任何情况下都不会冻结。但是,注释掉圆圈,并用再次显示图形替换它,它将随机冻结。令人沮丧的是,有时会,有时不会。有

我正在做的一个程序有问题。偶尔,它会结冰。没有错误或任何东西

这个游戏是一个多人游戏,你可以驾驶一艘船四处飞行。其他玩家和电源的图片根据您的位置移入和移出视图。在大多数情况下,它工作得很好,但在某些情况下,它会锁定

我一直追踪到它在一个表面撞击另一个表面。(SDL_BlitSurface)

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

我有大量的代码检查空曲面,但它似乎并没有阻止它。 我还将其设置为将所有图形的信息输出到一个文件(例如宽度、高度、内存中的位置、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 );
    }
}
职业玩家
{
Player();
int x;
int-y;
int xvel;
内特伊维尔;
SDL_表面*拉丝屏;
SDL_表面*ShipPic;
无效检查玩家距离();
无效检查\u通电\u距离();
无效更新();
};    
班级通电
{
int x;
int-y;
int型;
SDL_表面*通电图;
};
Player::Player()
{
应用_表面(0,0,播放机用户,ShipPic);
}
播放器::更新(播放器p[],开机pu[])
{
x+=xvel;
y+=yvel;
对于(int i=0;i

我注意到,当两个或更多的玩家彼此靠近时,它通常会冻结,并试图在他们的两个屏幕上使用相同的电源。但是,也不总是这样

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


以防万一,Apply_Surface()函数是什么样子的?我想这就是你在做你真正的闪电战的地方,如果这就是你遇到问题的地方,那对我们这些试图找出你的困境的人来说是很有用的。

好吧,我知道是什么了

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

结果发现它有一个bug,在我不知道的特定情况下,它会创建一个坏的曲面,在“大部分”时间都可以工作,但在正确的条件下,它会崩溃。例如,放置在屏幕上特定的x&y坐标处。(不确定)。旋转/缩放的图像在95%的时间内都能正常工作,因此很难确定问题所在

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

在那之后效果很好

希望这将有助于任何使用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;
之后(固定):

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

*表面会导致SDL_BlitSurface冻结吗*:任何东西都可以。发布你的代码会有帮助。有太多的代码要发布,但我添加了一些伪代码来展示它是如何工作的。如前所述,该计划本身运行良好。这很简单,有时当在绘图表面上点一个图形时,它会冻结。我找不到任何关于它冻结情况的可识别信息。任何一个曲面都没有偏离直线。这绝对是SDL_BlitSurface的一行代码,你的问题太模糊了。把你的问题归结为你认为是给你带来问题的代码的一个特定部分。你能把代码贴在行为不端的BlitSurface调用周围吗?
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 );
    }
}