2017-04-26 3 views
1

Je viens de commencer à utiliser C++ et SDL, et j'ai commencé à créer un clone de Breakout de base pour obtenir ma tête autour de la sémantique. Pour modulariser ce que j'ai jusqu'ici, j'ai créé deux fichiers d'en-tête core.h et paddle.h.correctement #including SDL dans le projet multi-dépôt

J'éprouve des difficultés avec notamment SDL correctement avec ces modules. Dans un premier temps, le projet compilé quand j'avais été le fichier principal breakout.cpp, paddle.h et paddle.cpp. A ce stade, la classe « Core » était situé dans breakout.cpp, et dès que je migré dans son propre fichier, le compilateur a commencé à se fâcher.

En l'état actuel, il est un jeu de très haut simple qui peut être illustré comme suit:

breakout ---> core ---> paddle 

Ce qui me porte à croire que je fais un contrôle recrue. Ou que je lie incorrectement les fichiers dans Makefile.

Voici le code:

breakout.cpp

#include "SDL2/SDL.h" 
#include "SDL2/SDL_image.h" 
#include <stdio.h> 
#include <string> 
#include "core.h" 

int main(int argc, char* args[]) { 
    Core gCore; 
    gCore.runGame(); 

    return 0; 
} 

core.h

#pragma once 

#include "paddle.h" 

class Core { 
public: 
    Core(); 
    ~Core(); 
    void runGame(); 

private: 
    static const int SCREEN_WIDTH = 640, SCREEN_HEIGHT = 480; 

    SDL_Window* gWindow; 
    SDL_Renderer* gRenderer; 

    Paddle* p1; 

    void render(); 
}; 

paddle.h

#pragma once 

#include <string> 

class Paddle { 

    friend class Core; 

public: 
    Paddle(SDL_Renderer* gRenderer); 
    ~Paddle(); 

    void free(); 

private: 
    static const int VELOCITY = 5; 
    int xPos, yPos, pWidth, pHeight; 

    SDL_Texture* pSprite; 
    SDL_Rect* pRect; 

    bool loadFromFile(SDL_Renderer* gRenderer, std::string path); 

    int getXPos(); int getYPos(); 
    int getWidth(); int getHeight(); 
}; 

core.cpp

#include "SDL2/SDL.h" 
#include "SDL2/SDL_image.h" 
#include <stdio.h> 
#include "paddle.h" 
#include "core.h" 

Core::Core() { 

    // Set up SDL 
    if (SDL_Init(SDL_INIT_VIDEO) < 0) { 
     printf("SDL could not initialise! SDL Error: %s\n", SDL_GetError()); 
    } 
    else { 
     if (!SDL_SetHint(SDL_HINT_RENDER_SCALE_QUALITY, "1")) { 
      printf("Warning: Linear texture filtering not enabled!"); 
     } 
     else { 
      gWindow = SDL_CreateWindow("SDL Tutorial", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, 
             SDL_WINDOW_SHOWN); 
      if (gWindow == NULL) { 
       printf("Could not create window. SDL Error: %s\n", SDL_GetError()); 
      } 
      else { 
       gRenderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC); 
       if (gRenderer == NULL) { 
        printf("Renderer could not be created! SDL Error: %s\n", SDL_GetError()); 
       } 
       else { 
        // Initialise renderer colour 
        SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); 

        // Initialise PNG loading 
        int imgFlags = IMG_INIT_PNG; 
        if (!(IMG_Init(imgFlags) & imgFlags)) { 
         printf("SDL_image could not be initialised! SDL_image Error: %s\n", IMG_GetError()); 
        } 
       } 
      } 
     } 
    } 
} 

Core::~Core() { 
    SDL_DestroyRenderer(gRenderer); gRenderer = NULL; 
    SDL_DestroyWindow(gWindow);  gWindow = NULL; 

    // Quit SDL subsystems 
    IMG_Quit(); 
    SDL_Quit(); 
} 

void Core::runGame() { 
    // Main loop flag 
    bool quit = false; 

    // Event handler 
    SDL_Event e; 

    // p1 = new Paddle(gRenderer); 

    while (!quit) { 
     while(SDL_PollEvent(&e) != 0) { 
      //User requests quit 
      if(e.type == SDL_QUIT) { 
       quit = true; 
      } 
     } 

     // Clear screen 
     SDL_SetRenderDrawColor(gRenderer, 0xFF, 0xFF, 0xFF, 0xFF); 
     SDL_RenderClear(gRenderer); 

     // Render game assets 
     render(); 

     // Update screen 
     SDL_RenderPresent(gRenderer); 
    } 
} 

void Core::render() { 
    // Set rendering space and render to screen 
    SDL_Rect pRenderQuad = { p1->xPos, p1->yPos, p1->pWidth, p1->pHeight }; 

    // Render to screen 
    SDL_RenderCopy(gRenderer, p1->pSprite, NULL, &pRenderQuad); 
} 

paddle.cpp

#include "SDL2/SDL.h" 
#include "SDL2/SDL_image.h" 
#include <stdio.h> 
#include <string> 
#include "paddle.h" 

Paddle::Paddle(SDL_Renderer* gRenderer) { 

    xPos = 300; yPos = 400; 
    pWidth = 0; pHeight = 0; 

    loadFromFile(gRenderer, "paddle.png"); 
} 

Paddle::~Paddle() { 
    free(); 
} 

bool Paddle::loadFromFile(SDL_Renderer* gRenderer, std::string path) { 
    // Get rid of preexisting texture 
    free(); 

    SDL_Texture* nTexture = NULL; 

    SDL_Surface* lSurface = IMG_Load(path.c_str()); 
    if (lSurface == NULL) { printf("Unable to load image %s! SDL_image Error: %s\n", path.c_str(), IMG_GetError()); } 
    else { 
     nTexture = SDL_CreateTextureFromSurface(gRenderer, lSurface); 
     if (nTexture == NULL) { printf("Unable to load texture from %s! SDL Error: %s\n", path.c_str(), SDL_GetError()); } 
     else { 
      pWidth = lSurface->w; 
      pHeight = lSurface->h; 
     } 

     SDL_FreeSurface(lSurface); // Surface no longer needed 
    } 

    pSprite = nTexture; 
    return pSprite != NULL; 
} 

void Paddle::free() { 
    if (pSprite != NULL) { 
     SDL_DestroyTexture(pSprite); 
     pWidth = 0; pHeight = 0; 
    } 
} 

// Getter methods 
int Paddle::getXPos() { return xPos; }  int Paddle::getYPos() { return yPos; } 
int Paddle::getWidth() { return pWidth; } int Paddle::getHeight() { return pHeight; } 

Et j'ai également inclus le Makefile, car il pourrait facilement y avoir quelque chose de mal là aussi.

Makefile

OBJS = breakout.cpp 
DEPS = paddle.h core.h 

CC = g++ 

COMPILER_FLAGS = -w 

LINKER_FLAGS = -lSDL2 -lSDL2_image 

OBJ_NAME = breakout 

%.o: %.cpp $(DEPS) 
    $(CC) -c -o [email protected] $< $(COMPILER_FLAGS) 

all : $(OBJS) 
    $(CC) $(OBJS) $(COMPILER_FLAGS) $(LINKER_FLAGS) paddle.cpp core.cpp -o $(OBJ_NAME) 

Erreur journal

g++ breakout.cpp -w -lSDL2 -lSDL2_image paddle.cpp core.cpp -o breakout 
/tmp/cc0H2fKM.o: In function `Paddle::loadFromFile(SDL_Renderer*, std::basic_string<char, std::char_traits<char>, std::allocator<char> >)': 
paddle.cpp:(.text+0x111): undefined reference to `IMG_Load' 
paddle.cpp:(.text+0x121): undefined reference to `SDL_GetError' 
paddle.cpp:(.text+0x15a): undefined reference to `SDL_CreateTextureFromSurface' 
paddle.cpp:(.text+0x16a): undefined reference to `SDL_GetError' 
paddle.cpp:(.text+0x1b8): undefined reference to `SDL_FreeSurface' 
/tmp/cc0H2fKM.o: In function `Paddle::free()': 
paddle.cpp:(.text+0x203): undefined reference to `SDL_DestroyTexture' 
/tmp/ccDHGaLY.o: In function `Core::Core()': 
core.cpp:(.text+0x12): undefined reference to `SDL_Init' 
core.cpp:(.text+0x1e): undefined reference to `SDL_GetError' 
core.cpp:(.text+0x44): undefined reference to `SDL_SetHint' 
core.cpp:(.text+0x86): undefined reference to `SDL_CreateWindow' 
core.cpp:(.text+0xa1): undefined reference to `SDL_GetError' 
core.cpp:(.text+0xd1): undefined reference to `SDL_CreateRenderer' 
core.cpp:(.text+0xee): undefined reference to `SDL_GetError' 
core.cpp:(.text+0x127): undefined reference to `SDL_SetRenderDrawColor' 
core.cpp:(.text+0x138): undefined reference to `IMG_Init' 
core.cpp:(.text+0x149): undefined reference to `SDL_GetError' 
/tmp/ccDHGaLY.o: In function `Core::~Core()': 
core.cpp:(.text+0x17a): undefined reference to `SDL_DestroyRenderer' 
core.cpp:(.text+0x195): undefined reference to `SDL_DestroyWindow' 
core.cpp:(.text+0x1a5): undefined reference to `IMG_Quit' 
core.cpp:(.text+0x1aa): undefined reference to `SDL_Quit' 
/tmp/ccDHGaLY.o: In function `Core::runGame()': 
core.cpp:(.text+0x1ea): undefined reference to `SDL_PollEvent' 
core.cpp:(.text+0x218): undefined reference to `SDL_SetRenderDrawColor' 
core.cpp:(.text+0x228): undefined reference to `SDL_RenderClear' 
core.cpp:(.text+0x244): undefined reference to `SDL_RenderPresent' 
/tmp/ccDHGaLY.o: In function `Core::render()': 
core.cpp:(.text+0x2d1): undefined reference to `SDL_RenderCopy' 
collect2: ld returned 1 exit status 
make: *** [all] Error 1 

je aimerais serait vraiment apprécier votre soutien non seulement sur le problème à portée de main. Mais aussi si des suggestions générales sur mon code peuvent être faites.

Merci

+0

L'éditeur de liens ne trouve pas la fonction dans les bibliothèques SDL. Cela peut être causé par l'ordre des arguments de l'éditeur de liens, essayez de placer le 'LINKER_FLAGS' après les fichiers .cpp dans votre Makefile. –

+2

'-w'? * Pourquoi? * - – Quentin

+0

Merci pour la suggestion Karsten Koop, il a résolu le problème immédiatement! Et Quentin, en utilisant un drapeau de suppression d'avertissement est certainement une mauvaise idée. L'inclusion de ce drapeau était une conséquence directe de suivre un certain tutoriel SDL. – manderc3

Répondre

3

L'ordre des drapeaux sur votre commutateur de compilation est important.

Les bibliothèques à transmettre à l'éditeur de liens doit être le dernier.

Et en utilisant un -w n'a pas de sens car il est généralement -W (capital) suivi d'une sorte de directive, comme -Werror -Wall etc.

vous conseil: retirer le drapeau -w et déplacer le -l bascule à la fin.

+1

Cela n'a pas vraiment de sens - c'est bien pire que de ne pas l'avoir du tout ('-w' est désactivé-all-warnings dans gcc). – keltar