2017-04-26 42 views
1

我剛開始使用C++和SDL,並且我已經開始創建一個基本的Breakout克隆,以便讓我的頭部圍繞語義。爲了模塊化我到目前爲止所做的,我創建了兩個頭文件core.hpaddle.h正確#在多字段項目中包括SDL

我很難正確地將SDL包含在這些模塊中。最初,我所有編譯的項目是主文件breakout.cpp,paddle.hpaddle.cpp。在這個階段,'Core'類位於breakout.cpp,一旦我將它移植到它自己的文件中,編譯器就開始感到不安。

因爲它的立場,那就是可以進行如下說明一個非常簡單的設置:

breakout ---> core ---> paddle 

這使我相信,我想提出一個新秀監督。或者我在Makefile中錯誤地鏈接了這些文件。

下面是代碼:

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

而且我也包括Makefile文件,因爲很容易被一些錯誤也有。

的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) 

錯誤日誌

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 

我會很感激的不只是眼前的問題,您的支持。但是,如果有關於我的代碼的任何一般性建議可以做出。

謝謝

+0

鏈接器在SDL庫中找不到該函數。這可能是由鏈接器的參數順序引起的,請嘗試將'LINKER_FLAGS'放在Makefile中的.cpp文件之後。 –

+2

'-w'? *爲什麼?* - – Quentin

+0

謝謝您的建議Karsten Koop,它立即解決了問題!而昆汀,使用警告清除標誌肯定是一個壞主意。包含該標誌是遵循某個SDL教程的直接結果。 – manderc3

回答

3

編譯器開關問題上的標誌順序。

要傳遞給鏈接器的庫應該是最後一個。

,並使用-w是沒有意義的,因爲它通常是-W(資本),其次是某種指令,如-Werror -Wall等

Suggesto:刪除-w標誌和移動-l切換到最後。

+1

不完全沒有任何意義 - 僅僅比沒有它更糟糕('-w'是禁用 - gcc中的所有警告)。 – keltar