Ошибка сегментации при вызове функции
Когда я компилирую с помощью gcc, я получаю ошибку сегментации в функциях GetPixel и столкновениях.
Но когда я помещаю эти две функции в отдельный файл.c с главной функцией для их проверки, они работают отлично
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <SDL/SDL.h>
#include <SDL/SDL_image.h>
#include <SDL/SDL_ttf.h>
typedef struct {
SDL_Rect pos_joueur;
int vie_joueur, nbr_indice;
int temps;
SDL_Surface * image_j;
} joueur;
void afficher_bg(SDL_Surface * ecran, SDL_Surface * bg, SDL_Rect pos_bg);
void initialiser_personnage(joueur * j);
void afficher_personnage(joueur J, SDL_Surface * ecran);
void scroll(SDL_Rect *camera, int direction);
SDL_Color GetPixel(SDL_Surface * pSurface, int x, int y);
int collision_entite_bg(int x, int y, SDL_Surface * map_jeu,
SDL_Surface * map_obstacles, SDL_Surface * map_enigmes);
int main(int argc, char *argv[])
{
SDL_Surface *ecran = NULL, *bg = NULL, *map_obstacles = NULL, *map_enigmes =
NULL;
joueur j;
SDL_Rect pos_bg;
pos_bg.x = 880, pos_bg.y = 1260, pos_bg.h = 768, pos_bg.w = 100;
map_obstacles = IMG_Load("map_obstacles.png");
map_enigmes = IMG_Load("map_enigmes.png");
int continuer_jeu = 1;
SDL_Event event;
SDL_Init(SDL_INIT_VIDEO);
ecran = SDL_SetVideoMode(1360, 768, 32, SDL_HWSURFACE | SDL_DOUBLEBUF);
afficher_bg(ecran, bg, pos_bg);
initialiser_personnage(&j);
afficher_personnage(j, ecran);
while (continuer_jeu == 1)
{
while (SDL_PollEvent(&event))
{
switch (event.type)
{
case SDL_QUIT:
continuer_jeu = 0;
break;
case SDL_KEYDOWN:
switch (event.key.keysym.sym)
{
case SDLK_UP: // Flèche haut
direction = 1;
break;
case SDLK_DOWN: // Flèche bas
direction = 2;
break;
case SDLK_RIGHT: // Flèche droite
direction = 4;
break;
case SDLK_LEFT: // Flèche gauche
direction = 3;
break;
}
break;
}
if (continuer_jeu == 0)
break;
if (collision_entite_bg(pos_bg.x + 1300 / 2, pos_bg.y + 768 / 2, bg,
map_obstacles, map_enigmes))
{
scroll(&pos_bg, direction);
printf("\na\n");
afficher_bg(ecran, bg, pos_bg);
afficher_personnage(j, ecran);
}
}
SDL_Flip(ecran);
}
SDL_FreeSurface(map_obstacles);
SDL_FreeSurface(map_enigmes);
SDL_FreeSurface(ecran);
SDL_FreeSurface(bg);
SDL_Quit();
return EXIT_SUCCESS;
}
void afficher_bg(SDL_Surface * ecran, SDL_Surface * bg, SDL_Rect pos_bg)
{
bg = IMG_Load("map.png");
SDL_BlitSurface(bg, &pos_bg, ecran, NULL);
SDL_Flip(ecran);
}
void initialiser_personnage(joueur * j)
{
j->pos_joueur.x = 605;
j->pos_joueur.y = 274;
j->vie_joueur = 100;
j->nbr_indice = 0;
j->temps = 1800; //s
j->image_j = IMG_Load("pirate.png");
}
void afficher_personnage(joueur j, SDL_Surface * ecran)
{
SDL_BlitSurface(j.image_j, NULL, ecran, &j.pos_joueur);
SDL_Flip(ecran);
}
SDL_Color GetPixel(SDL_Surface * pSurface, int x, int y)
{
SDL_Color color;
Uint32 col = 0;
char* pPosition = (char*) pSurface->pixels;
pPosition += (pSurface->pitch * y);
pPosition += (pSurface->format->BytesPerPixel * x);
memcpy(&col, pPosition, pSurface->format->BytesPerPixel);
SDL_GetRGB(col, pSurface->format, &color.r, &color.g, &color.b);
return (color);
}
int collision_entite_bg(int x, int y, SDL_Surface * map_jeu,
SDL_Surface * map_obstacles, SDL_Surface * map_enigmes)
{
SDL_Color color_map_jeu, color_map_obstacles, color_map_enigmes;
color_map_jeu = GetPixel(map_jeu, x, y);
color_map_obstacles = GetPixel(map_obstacles, x, y);
color_map_enigmes = GetPixel(map_enigmes, x, y);
if (color_map_jeu.r != color_map_enigmes.r
|| color_map_jeu.g != color_map_enigmes.g
|| color_map_jeu.b != color_map_enigmes.b)
return 2;
else if (color_map_jeu.r != color_map_obstacles.r
|| color_map_jeu.g != color_map_obstacles.g
|| color_map_jeu.b != color_map_obstacles.b)
return 1;
else
return 0;
}
void scroll(SDL_Rect *camera, int direction)
{
int speed = 5;
if (direction == 1)
{
camera->x += speed;
camera->y -= speed;
}
else if (direction == 2)
{
camera->y += speed;
camera->x -= speed;
}
else if (direction == 3)
{
camera->x += speed;
camera->y += speed;
}
else if (direction == 4)
{
camera->x -= speed;
camera->y -= speed;
}
if (camera->x < 0)
{
camera->x = 0;
//coll->x-=2;
}
if (camera->y < 0)
{
camera->y = 0;
//coll->y-=2;
}
/*if( camera->x > collisionMap->w - camera->w )
{
camera->x = collisionMap->w - camera->w ;
coll->x=2;
}
if( camera->y > collisionMap->h - camera->h )
{
camera->y = collisionMap->h - camera->h ;
coll->y+=2;
}*/
}
1 ответ
Исходя из комментария keltar:
Когда вы звоните:
afficher_bg(ecran, bg, pos_bg);
Вы хотите изменить значение bg (которое является указателем). Но так как он называется по значению, вы можете только изменить *bg
, назначение указателя.
Это можно исправить, если вы вызываете его с адресом переменной указателя.
afficher_bg(ecran, &bg, pos_bg);
Но для того, чтобы это работало, вам также нужно изменить реализацию функции, чтобы она изменяла указанное значение, а не копию переменной.
void afficher_bg(SDL_Surface * ecran, SDL_Surface ** bg, SDL_Rect pos_bg) // you need a pointer to the pointer
{
*bg = IMG_Load("map.png"); //then change the pointer by dereferencing the pointer to pointer
SDL_BlitSurface(*bg, &pos_bg, ecran, NULL); //the same here
SDL_Flip(ecran);
}
Но обычно это то, что вы можете найти и исправить с помощью отладчика.