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
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. –
'-w'? * Pourquoi? * - – Quentin
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