我剛開始使用C++和SDL,並且我已經開始創建一個基本的Breakout克隆,以便讓我的頭部圍繞語義。爲了模塊化我到目前爲止所做的,我創建了兩個頭文件core.h
和paddle.h
。正確#在多字段項目中包括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
我會很感激的不只是眼前的問題,您的支持。但是,如果有關於我的代碼的任何一般性建議可以做出。
謝謝
鏈接器在SDL庫中找不到該函數。這可能是由鏈接器的參數順序引起的,請嘗試將'LINKER_FLAGS'放在Makefile中的.cpp文件之後。 –
'-w'? *爲什麼?* - – Quentin
謝謝您的建議Karsten Koop,它立即解決了問題!而昆汀,使用警告清除標誌肯定是一個壞主意。包含該標誌是遵循某個SDL教程的直接結果。 – manderc3