程序接收信号SIGSEGV,分段故障。在al_draw_tinted_bitmap中(位图= 0x0,tint = ...,dx = 0,dy = 0,flags = 0)

问题描述 投票:0回答:2

我在尝试编译这个游戏时遇到了问题。我正在使用Allegro 5库来编程PacMan视频游戏。问题发生在运行时,它只打开可执行文件并立即关闭。当我使用gcc的调试器时,我得到的错误是下一个:

"Thread 1 "a.out" received signal SIGSEGV, Segmentation fault.
0x00007ffff79362af in al_draw_tinted_bitmap (bitmap=0x0, tint=..., dx=0, dy=0, 
    flags=0) at /home/pakoxtror/allegro-5.0/src/bitmap.c:316
aviso: El archivo fuente es más reciente que el ejecutable.
316    al_draw_tinted_bitmap_region(bitmap, tint, 0, 0,"

我在一些论坛上搜索他们说问题是位图没有设置为null。我试图纠正它但仍然没有发生任何事情。这是代码:

#include <allegro5/allegro.h>
#include <allegro5/allegro_font.h>
#include <allegro5/allegro_ttf.h>
#include <allegro5/allegro_native_dialog.h>
#include <cstdlib>
#include <stdio.h>
#include <stdlib.h>
#include <time.h>
#include <allegro5/allegro_image.h>

#define MAXFILAS 20 //eje y
#define MAXCOLS 31 // eje x
#define ScreenWidth 800
#define ScreenHeight 600

ALLEGRO_DISPLAY *display;
ALLEGRO_EVENT_QUEUE *event_queue;
ALLEGRO_BITMAP *buffer = NULL;
ALLEGRO_BITMAP *roca= NULL;  //son variables
ALLEGRO_BITMAP *comida= NULL;
ALLEGRO_BITMAP *pacbmp= NULL;//declarar una variable para la imagen
ALLEGRO_BITMAP *pacman= NULL;////declarar una variable para la imagen pero más pequeño
ALLEGRO_BITMAP *muerte= NULL;


int dir = 4;
int px = 30 * 14, py = 30 * 17;
int anteriorpx, anteriorpy;

char mapa[MAXFILAS][MAXCOLS] = {
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
    "X o o|o o o XXXXX o o o| o oX",
    "X XXX XXXXX XXXXX XXXXX XXX X",
    "X XXX XXXXX XXXXX XXXXX XXX X",
    "X      o|o o o o o o|o      X",
    "XoXXXoXX XXXXXXXXXXX XXoXXXoX",
    "X    |XX     XXX     XX     X",
    "X XXXoXXXXXX XXX XXXXXX XXX X",
    "X XXXoXX ooo|ooo|ooo XXoXXX X",
    " o   |XX XXXXXXXXXXX XX|   o ",
    "X XXXoXX XXXXXXXXXXX XXoXXX X",
    "XoXXXoXX oo  ooo ooo XXoXXXoX",
    "X XXXoXXXXXX XXX XXXXXXoXXX X",
    "Xo    XX     XXX     XX    oX",
    "X XXXoXX XXXXXXXXXXX XXoXXX X",
    "XoXXX| o| o o o o o |o |XXXoX",
    "X XXXoXXXX XXXXXXXX XXX XXX X",
    "XoXXXoXXXX          XXX XXXoX",
    "X  o |o o  XXXXXXXX o o| o  X",
    "XXXXXXXXXXXXXXXXXXXXXXXXXXXXX",
};

void dibujarmapa() {
    int row, col;
    for (row = 0; row < MAXFILAS; row++)
    {
        for (col = 0; col < MAXCOLS; col++)
        {
            if (mapa[row][col] == 'X')
            {
                al_draw_bitmap(roca, col * 30, row * 30, 0);
            }
            else if (mapa[row][col] == 'o')
            {
                al_draw_bitmap(comida, col * 30, row * 30, 0);
                if (py / 30 == row && px / 30 == col)
                {
                    mapa[row][col] = ' ';
                }
            }
        }
    }
}

void pantalla()
{

    al_draw_bitmap(buffer, 0, 800, 600);
}

void dibujarpersonaje() {
    al_draw_bitmap_region(pacman, dir * 33, 0, 0, 0, 33, 33, 0);//coordenadas para donde vamos a tomar la imagen del jugador en este caso dir*33 y 0 despues dos coordenadas donde vamos a pegar la imagen 0,0 y por ultimo las dimensiones de la imagen en este caso 33, 33
    al_draw_bitmap(pacman, px, py, 0);//para que el cuadro pacman tenga transparencia, creo que no es necesario en nuestro juego
}

bool gameover() {
    int row, col;
    for (row = 0; row < MAXFILAS; row++) {
        for (col = 0; col < MAXCOLS; col++) {
            if (mapa[row][col] == 'o') {
                return true;
            }
        }
    }
    return false;
};

class fantasma {
    ALLEGRO_BITMAP  *enemigobmp;
    ALLEGRO_BITMAP  *enemigo;
    int fdir;
    int _x, _y;

public:
    fantasma(int x, int y); //constructor
    void dibujarfantasma() const;
    void moverfantasma();
    void choquepacman();
};
fantasma::fantasma(int x, int y) {
    _x = x;
    _y = y;
    fdir = rand() % 4;
    enemigo = al_create_bitmap(30, 30);
    enemigo = al_load_bitmap("enemigo.bmp");
}
void fantasma::dibujarfantasma() const {
    al_draw_bitmap_region(enemigo, dir * 33, 0, 0, 0, 30, 30, 0);
    al_draw_bitmap(enemigo, _x, _y, 0);
}

void fantasma::choquepacman() {
    if ((py == _y && px == _x) || (_y == anteriorpy && _x == anteriorpx)) {
        for (int j = 0; j <= 5; j++) {
            al_destroy_bitmap(pacman);
            al_destroy_bitmap(buffer);
            dibujarmapa();

            al_draw_bitmap_region(muerte, j * 33, 0, 0, 0, 33, 33, 0);
            al_draw_bitmap(pacman, px, py, 0);

            pantalla();
            //al_rest(80);
        }
        px = 30 * 14;
        py = 30 * 17;
        dir = 4;
    }
}
void fantasma::moverfantasma() {
    dibujarfantasma();
    choquepacman();
    if (mapa[_y / 30][_x / 30] == '|') {
        fdir = rand() % 4;
    }


    if (fdir == 0) {
        if (mapa[_y / 30][(_x - 30) / 30] != 'X')_x -= 30;
        else fdir = rand() % 3;
    }
    else if (fdir == 1) {
        if (mapa[_y / 30][(_x + 30) / 30] != 'X')_x += 30;
        else fdir = rand() % 3;
    }
    if (fdir == 2) {
        if (mapa[_y - 30 / 30][(_x) / 30] != 'X')_y -= 30;
        else fdir = rand() % 4;
    }
    if (fdir == 3) {
        if (mapa[_y + 30 / 30][(_x) / 30] != 'X')_y += 30;
        else fdir = rand() % 4;
    }
    //rutina atajo

    if (_x <= -30) {
        _x = 870;
    }
    else if (_x >= 870) _x = -30;
}



int main(int argc, char **argv) {
    if (!al_init()) {
        fprintf(stderr, "failed to initialize allegro!\n");
        return -1;
    }

    ALLEGRO_DISPLAY *display = NULL;

    al_set_new_display_flags(ALLEGRO_WINDOWED | ALLEGRO_RESIZABLE);
    display = al_create_display(ScreenWidth, ScreenHeight);
    al_set_window_position(display, 200, 100);
    al_set_window_title(display, "SAME");
    display = al_create_display(800, 600);

    ALLEGRO_KEYBOARD_STATE keyState;
    /*ALLEGRO_TIMER *timer;
    ALLEGRO_EVENT_QUEUE *event_queue;*/

    al_init();
    al_install_keyboard();
    al_init_font_addon();

    /*int game_initialized;
    int FPS = 60.0;
    int game_active;
    int can_change;*/
    buffer = al_create_bitmap(880, 600); //EJE X y Y POR 30
    roca = al_load_bitmap("roca.bmp");
    pacman = al_load_bitmap("pacman.bmp");
    pacman = al_create_bitmap(33, 33);
    comida = al_load_bitmap("comida.bmp");
    muerte = al_load_bitmap("muerte.bmp");


    al_set_target_backbuffer(display);

    ALLEGRO_COLOR electricBlue = al_map_rgb(44, 117, 255);
    /*ALLEGRO_TIMER *timer = al_create_timer(1.0 / FPS);
    ALLEGRO_EVENT_QUEUE *event_queue = al_create_event_queue();
    al_register_event_source(event_queue, al_get_display_event_source(display));
    al_register_event_source(event_queue, al_get_keyboard_event_source());
    al_register_event_source(event_queue, al_get_timer_event_source(timer));
    al_start_timer(timer); //novariables after this
    ALLEGRO_KEYBOARD_STATE keyState;*/
    al_draw_bitmap(buffer, 0, 0, 0);
    al_flip_display();


    fantasma A(30 * 2, 30 * 3);
    fantasma B(30 * 15, 30 * 15);
    fantasma C(30 * 2, 30 * 3);
    fantasma D(30 * 15, 30 * 15);
    fantasma E(30 * 2, 30 * 3);
    fantasma F(30 * 15, 30 * 15);
    fantasma G(30 * 2, 30 * 3);
    fantasma H(30 * 15, 30 * 15);

    while (!al_key_down(&keyState, ALLEGRO_KEY_ESCAPE) && gameover()) {
        //ALLEGRO_EVENT events;
        //al_wait_for_event(event_queue, &events);
        al_get_keyboard_state(&keyState);

        anteriorpx = px;
        anteriorpy = py;

        if (al_key_down(&keyState, ALLEGRO_KEY_DOWN))
        {
            dir = 3;
        }
        else if (al_key_down(&keyState, ALLEGRO_KEY_UP))
        {
            dir = 2;
        }

        else if (al_key_down(&keyState, ALLEGRO_KEY_RIGHT))
        {
            dir = 1;
        }

        else if (al_key_down(&keyState, ALLEGRO_KEY_LEFT))
        {
            dir = 0;

        }
        if (dir == 0)
        {
            if (mapa[py / 30][(px - 30) / 30] != 'X') {
                px -= 30;

            }
        }
        else {
            dir = 4;
        }

        if (dir == 1) {
            if (mapa[py / 30][(px + 30) / 30] != 'X') {
                px += 30;
            }
        }
        else dir = 4;

        if (dir == 2) {
            if (mapa[py / 30][(px - 30) / 30] != 'X') {
                px -= 30;
            }
        }
        else dir = 4;

        if (dir == 3) {
            if (mapa[py / 30][(px + 30) / 30] != 'X') {
                px += 30;
            }
        }
        else dir = 4;

        //rutina para atajo
        if (px <= -30) {
            px = 870;
        }
        else if (px >= 870) {
            px = -30;
        }
        al_destroy_bitmap(buffer);
        dibujarmapa();
        pantalla();
        dibujarpersonaje();
        A.moverfantasma();
        B.moverfantasma();
        C.moverfantasma();
        D.moverfantasma();
        E.moverfantasma();
        F.moverfantasma();
        G.moverfantasma();
        H.moverfantasma();

        al_destroy_bitmap(pacman);
        al_draw_bitmap_region(pacman, 4 * 33, 0, 0, 0, 33, 33, 0);
        al_draw_bitmap(pacman, px, py, 0);
        pantalla();
    };
    printf("\npresione la barra espaciadora y luego enter para continuar");
    while (getchar() != ' ');
    return 0;
}
c++ segmentation-fault 2d-games sigsegv allegro5
2个回答
0
投票

SIGSEV是内存越界错误,因此您可能需要检查边界情况。确保你的MAXFILAS和MAXCOLS足够大。你能告诉我们你的al_draw_bitmap函数吗?


0
投票

如果仔细查看调试器的输出,答案很清楚。

传递给al_draw_tinted_bitmap的'bitmap'参数为NULL(0x0)。

如果你传递一个NULL指针,Allegro可能会崩溃也可能不会崩溃,这取决于它的错误检查有多强大。通常在调试模式下,allegro会断言位图不是NULL。

因此,在加载之后以及将它们传递给任何allegro绘图函数之前,请确保所有位图都有效(非空)。

© www.soinside.com 2019 - 2024. All rights reserved.