2017-04-26 21 views
1

私はC++とSDLを使い始めましたが、セマンティクスの頭を掴むために基本的なブレークアウトクローンを作成しました。これまでのモジュール化のために、私はcore.hpaddle.hという2つのヘッダファイルを作成しました。マルチプロジェクトプロジェクトで#SDLを正しく組み込みました

これらのモジュールでSDLを正しく組み込むことができません。最初は、私が持っていたすべてがメインファイルbreakout.cpp,paddle.hおよびpaddle.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ライブラリで機能を見つけられません。これは、リンカーへの引数の順序によって引き起こされる可能性があります。Makefileに.cppファイルの後に 'LINKER_FLAGS'を置いてみてください。 –

+2

'-w'? *なぜ?* - – Quentin

+0

Karsten Koopの提案をありがとう、すぐに問題を解決しました!クエンティンは、警告除去フラグを使用することは、確かに悪い考えです。そのフラグを含めることは、特定のSDLチュートリアルを実行することによる直接の結果でした。 – manderc3

答えて

3

コンパイラスイッチのフラグの順序は重要です。

リンカーに渡すライブラリは最後にする必要があります。このよう-Werror -Wallなどとして

そして、それは通常、ディレクティブのいくつかの種類が続い-W(首都)だとして-wを使用しても意味がありません、

Suggesto:-wフラグを削除し、-lを移動最後に切り替えます。

+1

全く意味をなさないわけではありません。それをまったく持っていないよりもはるかに悪いです( '-w'はgccのdisable-all-warningsです)。 – keltar

関連する問題