调用函数时出现分段错误

时间:2018-04-26 22:58:42

标签: c sdl sdl-1.2

当我使用gcc编译时,我在GetPixel和碰撞函数中遇到了分段错误。

但是,当我将这两个函数放在他们自己的.c中并使用main函数来测试它们时,它们完美地工作

#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 个答案:

答案 0 :(得分:0)

从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);
}

但通常这是您可以使用调试器找到并修复的内容。

相关问题