C++ SDL/C++;(加速)黑屏

C++ SDL/C++;(加速)黑屏,c++,sdl,C++,Sdl,我正在尝试用C++/SDL制作某种“引擎”。因此,我遵循LazyFoo的教程,搜索了其他地方/视频[SDL/C++]。 一切都很好,直到我把代码分为两类。它只是Game.h/Game.cpp和main.cpp,但我认为最好将加载图像的代码部分与加载和破坏表面/纹理的游戏类(游戏类)分开 因此,我将代码复制/粘贴到另一个类。我复制/粘贴的是两个布尔函数textureBMP和textureIMG,所有内容都保持不变。在我将代码复制/粘贴到另一个类之前,一切都很正常,所以我不知道这是怎么回事 还有一个

我正在尝试用C++/SDL制作某种“引擎”。因此,我遵循LazyFoo的教程,搜索了其他地方/视频[SDL/C++]。 一切都很好,直到我把代码分为两类。它只是Game.h/Game.cpp和main.cpp,但我认为最好将加载图像的代码部分与加载和破坏表面/纹理的游戏类(游戏类)分开

因此,我将代码复制/粘贴到另一个类。我复制/粘贴的是两个布尔函数textureBMP和textureIMG,所有内容都保持不变。在我将代码复制/粘贴到另一个类之前,一切都很正常,所以我不知道这是怎么回事

还有一个小问题,我组织代码的方式是否正确?我希望一开始就养成良好的习惯,即使是小项目,比如这个只是为了学习的小项目。 提前谢谢

图像.h

#pragma once
#include "Game.h"

class Image
{
public:
    Image();
    ~Image();

    Game game;

    SDL_Surface *gBMP = NULL;
    SDL_Texture *tBMP = NULL;
    SDL_Surface *gIMG = NULL;
    SDL_Texture *tIMG = NULL;

    bool textureBMP(char *mediaLocation, bool SetColorKey, int red, int green, int blue);
    bool textureIMG(char *mediaLocation, int imgFlags);
};
bool textureBMP(char *mediaLocation, <...>, SDL_Renderer *render);
bool textureIMG(char *mediaLocation, <...>, SDL_Renderer *render);
Image.cpp

#include "Image.h"

Image::Image()
{
}


Image::~Image()
{
}

bool Image::textureBMP(char *mediaLocation, bool SetColorKey, int red, int green, int blue) {

    gBMP = SDL_LoadBMP(mediaLocation);

    if (gBMP == NULL) {
        printf("Nao foi possivel carregar a imagem %s,por causa do seguinte erro: \n %s \n", mediaLocation, SDL_GetError());
        return false;
    }
    else {

        if (SetColorKey) {

            SDL_SetColorKey(gBMP, 1, SDL_MapRGB(gBMP->format, red, green, blue));

        }

        tBMP = SDL_CreateTextureFromSurface(game.renderer, gBMP);
        SDL_FreeSurface(gBMP);

    }

    return true;
}

bool Image::textureIMG(char *mediaLocation, int imgFlags) {

    if (!(IMG_Init(imgFlags) & imgFlags)) {

        printf("SDL_image não pode ser inicializada! SDL_image Error: %s\n", IMG_GetError());
        return false;
    }
    else {

        gIMG = IMG_Load(mediaLocation);
        tIMG = SDL_CreateTextureFromSurface(game.renderer, gIMG);
        SDL_FreeSurface(gIMG);

    }

    return true;
}
游戏

#pragma once
#include <SDL.h>
#include <SDL_image.h>
#include <iostream>
#include <string>

class Game
{

public:

    const int SCREEN_WIDTH = 800;
    const int SCREEN_HEIGHT = 600;

    bool running;

    SDL_Event event;

    SDL_Window *gWindow = NULL;
    SDL_Renderer *renderer = NULL;
    SDL_Surface *gScreenSurface = NULL;

    Game();
    ~Game();

    bool initEngine(char *windowName);

    void freeSurface(SDL_Surface *surfaceName);
    void freeTexture(SDL_Texture *textureName);
    void destroyRenderer();
    void destroyWindow();

};
#pragma一次
#包括
#包括
#包括
#包括
班级游戏
{
公众:
屏幕宽度=800;
屏幕上的常数=600;
布尔跑;
SDL_事件;
SDL_窗口*gWindow=NULL;
SDL_渲染器*渲染器=NULL;
SDL_表面*gScreenSurface=NULL;
游戏();
~Game();
bool initEngine(char*windowName);
空隙自由表面(SDL_表面*表面名称);
无孔隙纹理(SDL_纹理*纹理名称);
void();
空窗口();
};
Game.cpp

#include "Game.h"

Game::Game()
{
}


Game::~Game()
{
}

bool Game::initEngine(char *windowName) {

    bool initSucess = true;

    if (SDL_Init(SDL_INIT_VIDEO) < 0) {

        printf("A Engine não foi iniciada pelo seguinte erro: \n %s \n", SDL_GetError());
        initSucess = false;
        return initSucess;
    }
    else {

        gWindow = SDL_CreateWindow(windowName, SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, SCREEN_WIDTH, SCREEN_HEIGHT, SDL_WINDOW_SHOWN);
        renderer = SDL_CreateRenderer(gWindow, -1, SDL_RENDERER_ACCELERATED);

        if (gWindow == NULL) {

            printf("A janela não pode ser criada pelo seguinte erro: \n %s \n", SDL_GetError());
            initSucess = false;
            return initSucess;

        }
        else {

            gScreenSurface = SDL_GetWindowSurface(gWindow);

        }

    }


    return initSucess;
}

void Game::freeSurface(SDL_Surface *surfaceName) {

    SDL_FreeSurface(surfaceName);
    surfaceName = NULL;

}

void Game::freeTexture(SDL_Texture *textureName) {

    SDL_DestroyTexture(textureName);
    textureName = NULL;

}

void Game::destroyRenderer() {

    SDL_DestroyRenderer(renderer);
    renderer = NULL;

}

void Game::destroyWindow() {

    SDL_DestroyWindow(gWindow); 
    gWindow = NULL;

}
#包括“Game.h”
Game::Game()
{
}
游戏::~Game()
{
}
bool Game::initEngine(char*windowName){
bool initsuces=true;
if(SDL_Init(SDL_Init_视频)<0){
printf(“引擎错误:\n%s\n”,SDL_GetError());
initsuces=false;
回归成功;
}
否则{
gWindow=SDL_CreateWindow(显示的窗口名称、SDL_WINDOWPOS_未定义、SDL_WINDOWPOS_未定义、屏幕宽度、屏幕高度、SDL_窗口);
renderer=SDL_CreateRenderer(gWindow,-1,SDL_renderer_加速);
if(gWindow==NULL){
printf(“janela não pode ser criada pelo seguinte erro:\n%s\n”,SDL_GetError());
initsuces=false;
回归成功;
}
否则{
gScreenSurface=SDL_GetWindowSurface(gWindow);
}
}
回归成功;
}
虚空游戏::自由曲面(SDL_曲面*曲面名称){
SDL_自由曲面(曲面名称);
surfaceName=NULL;
}
空虚游戏::自由纹理(SDL_纹理*textureName){
SDL_破坏纹理(纹理名称);
textureName=NULL;
}
无效游戏::破坏渲染器(){
SDL_渲染器(渲染器);
渲染器=空;
}
无效游戏::销毁窗口(){
SDL_(格温多);
gWindow=NULL;
}
main.cpp

#include <iostream>
#include <SDL.h>
#include "Game.h"
#include "Image.h"

int main(int argc, char* args[]) {

    Game game;
    Image img;

    if (!game.initEngine("TESTE")) {
        printf("Falha ao iniciar! \n");
        return 0;
    }

    game.running = true;

    if (!img.textureBMP("res/bouncingball.bmp", true, 255, 0, 255))
        printf("Falha ao iniciar imagem!\n");

    if (!img.textureIMG("res/Tulips.jpg", IMG_INIT_JPG))
        printf("Falha ao iniciar imagem! \n");

    SDL_Rect stretchRect{ (game.SCREEN_WIDTH / 2) - 50, (game.SCREEN_HEIGHT / 2) - 50, 100, 100 };

    SDL_Rect stretchRect2{ 0, 0, game.SCREEN_WIDTH, game.SCREEN_HEIGHT };

    while (game.running) {

        while (SDL_PollEvent(&game.event) != 0) {

            switch (game.event.type) {

            case SDL_QUIT:

                game.running = false;
                game.freeSurface(game.gScreenSurface);
                game.freeTexture(img.tBMP);
                game.freeTexture(img.tIMG);
                game.destroyRenderer();
                game.destroyWindow();
                IMG_Quit();
                SDL_Quit();
                break;

            }//Switch Event END


        } // PollEvent END

        SDL_RenderCopy(game.renderer, img.tIMG, nullptr, &stretchRect2);
        SDL_RenderCopy(game.renderer, img.tBMP, nullptr, &stretchRect);
        SDL_RenderPresent(game.renderer);

        SDL_GL_SetSwapInterval(1);

    }// game.running END

    return 0;
}
if (!img.textureIMG("res/Tulips.jpg", IMG_INIT_JPG, game.renderer))
#包括
#包括
#包括“Game.h”
#包括“Image.h”
int main(int argc,char*args[]{
游戏;
图像img;
if(!game.initEngine(“TESTE”)){
printf(“Falha ao iniciar!\n”);
返回0;
}
game.running=true;
如果(!img.textureBMP(“res/bouncingball.bmp”,true,255,025))
printf(“Falha ao iniciar imagem!\n”);
if(!img.textureIMG(“res/Tulips.jpg”,img_INIT_jpg))
printf(“Falha ao iniciar imagem!\n”);
SDL_Rect stretchRect{(game.SCREEN_WIDTH/2)-50,(game.SCREEN_HEIGHT/2)-50100100};
SDL_Rect stretchRect2{0,0,game.SCREEN_WIDTH,game.SCREEN_HEIGHT};
同时(游戏、跑步){
while(SDL_PollEvent(&game.event)!=0){
开关(游戏.事件.类型){
案例SDL_退出:
game.running=false;
game.freeSurface(game.gScreenSurface);
自由纹理(img.tBMP);
游戏。自由纹理(img.tIMG);
game.destroyer();
游戏。破坏窗口();
IMG_Quit();
SDL_退出();
打破
}//开关事件结束
}//轮询事件结束
SDL_渲染副本(game.renderer、img.tIMG、nullptr和stretchRect2);
SDL_渲染副本(game.renderer、img.tBMP、nullptr和stretchRect);
SDL_RenderPresent(游戏渲染器);
SDL_GL_SetSwapInterval(1);
}//比赛结束
返回0;
}

我做了一些更改,现在它可以正常工作了。我改变了两件事,第一件是提供黑屏的部分,现在功能如下所示:

图像.h

#pragma once
#include "Game.h"

class Image
{
public:
    Image();
    ~Image();

    Game game;

    SDL_Surface *gBMP = NULL;
    SDL_Texture *tBMP = NULL;
    SDL_Surface *gIMG = NULL;
    SDL_Texture *tIMG = NULL;

    bool textureBMP(char *mediaLocation, bool SetColorKey, int red, int green, int blue);
    bool textureIMG(char *mediaLocation, int imgFlags);
};
bool textureBMP(char *mediaLocation, <...>, SDL_Renderer *render);
bool textureIMG(char *mediaLocation, <...>, SDL_Renderer *render);
另一个变化是,在Image.h之前包含了Game.h,在main.cpp中我包含了Game.h和Image.h,这会产生一个错误,对吗? 因此


Obs:我创建了一个答案,因为注释不允许使用代码

如果每个图像对象都有一个单独的游戏对象,您将如何渲染到一个渲染器?我无法以其他方式访问渲染器,可能会使其保持静态?@sadmachine static可以工作。在创建图像时传递渲染器也会发生变化。你现在拥有的是一个空值。有几种方法可以实现你想要的。但我认为最方便的方法是不要在Image类中存储游戏对象。加载图像时,将引用传递给渲染器。因此,不需要复制,也不必在每个图像对象中存储渲染器。回答自己的问题(并接受它)是可以的,只要它是一个真正的答案。如果您需要评论,通常最好编辑问题(不是在这种情况下,它是好的-只是为了将来)。我不明白你为什么会对include-guard有问题——它们会跳过部分代码,而不是显式地产生错误。好的,我会尽量记住它,谢谢!