我在尝试编译这个游戏时遇到了问题。我正在使用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;
}
SIGSEV是内存越界错误,因此您可能需要检查边界情况。确保你的MAXFILAS和MAXCOLS足够大。你能告诉我们你的al_draw_bitmap函数吗?
如果仔细查看调试器的输出,答案很清楚。
传递给al_draw_tinted_bitmap的'bitmap'参数为NULL(0x0)。
如果你传递一个NULL指针,Allegro可能会崩溃也可能不会崩溃,这取决于它的错误检查有多强大。通常在调试模式下,allegro会断言位图不是NULL。
因此,在加载之后以及将它们传递给任何allegro绘图函数之前,请确保所有位图都有效(非空)。