简体   繁体   English

程序收到信号SIGSEGV,分段故障。 在al_draw_tinted_bitmap中(位图= 0x0,色调= ...,dx = 0,dy = 0,标志= 0)

[英]Program received signal SIGSEGV, Segmentation fault. in al_draw_tinted_bitmap (bitmap=0x0, tint=…, dx=0, dy=0, flags=0)

I have a problem when trying to compile this game. 尝试编译此游戏时出现问题。 I am using the Allegro 5 library in order to program a PacMan Videogame. 我正在使用Allegro 5库来为PacMan Videogame编程。 The problem occurs in the runtime, it only opens the executable file and get closed inmediately. 该问题发生在运行时中,它仅打开可执行文件并立即被关闭。 When I use the debugger of gcc the error that I get is the next one: 当我使用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,"

I was searching at some forums where they stated that the problem was that the bitmap was not set to null. 我在一些论坛上搜索,他们说问题是位图未设置为null。 I tried to correct it but still nothing is happening. 我试图纠正它,但仍然没有任何反应。 Here is the code: 这是代码:

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

SIGSEV is a memory out-of-bounds error, so you might want to check your boundary cases. SIGSEV是内存超出范围错误,因此您可能需要检查边界情况。 Make sure your MAXFILAS and MAXCOLS are large enough. 确保您的MAXFILAS和MAXCOLS足够大。 Could you show us your al_draw_bitmap function? 您能告诉我们您的al_draw_bitmap函数吗?

The answer is clear if you look closely at the output from your debugger. 如果仔细查看调试器的输出,答案很明确。

The 'bitmap' parameter you passed to al_draw_tinted_bitmap is NULL (0x0). 您传递给al_draw_tinted_bitmap的'bitmap'参数为NULL(0x0)。

Allegro may or may not crash if you pass it a NULL pointer, depends on how robust it's error checking is. 如果您将NULL指针传递给Allegro,则它可能会崩溃也可能不会崩溃,这取决于它的错误检查的鲁棒性。 Usually in debug mode, allegro will assert that the bitmap is not NULL. 通常在调试模式下,Allegro会断言该位图不是NULL。

So make sure all your bitmaps are valid (Non NULL) after loading and before passing them to any allegro drawing functions. 因此,请确保在加载后以及将它们传递给任何allegro绘图函数之前,所有位图均有效(非NULL)。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM