SDL2 在背景图像上渲染按钮

问题描述

我正在使用 SDL2 制作用于练习的俄罗斯方块克隆。我正在制作一个菜单屏幕,但是我无法让按钮在背景上呈现 - 该按钮仍然存在并且它的功能退出程序),但我看不到该按钮。我的日志功能中的所有内容都按预期返回,即按钮位置和尺寸。以下是相关代码

main.cpp:

#include "gameengine.h"
#include "introstate.h"
#include "loguru.hpp"

int main(int argc,char *argv[]) {
    //Enable logging
    loguru::init(argc,argv);
    loguru::add_file("debug.log",loguru::Truncate,loguru::Verbosity_MAX);
    loguru::add_file("info.log",loguru::Verbosity_INFO);

    CGameEngine game;

    //Start the game engine up
    game.init("Tetris Game");

    //Load the beginning of the game,menu
    game.changeState(CIntroState::instance());

    //main loop
    while(game.running()) {
        game.handleEvents();
        game.update();
        game.draw();
    }

    game.cleanup();

    return 0;
}

gamestate.h:

#include "gameengine.h"
#include "loguru.hpp"

class CGameState {
    public:
        virtual void init(CGameEngine* game) = 0;
        virtual void cleanup() = 0;

        virtual void pause() = 0;
        virtual void resume() = 0;

        virtual void handleEvents(CGameEngine* game) = 0;
        virtual void update(CGameEngine* game) = 0;
        virtual void draw(CGameEngine* game) = 0;

        void changeState(CGameEngine* game,CGameState* state) {
            game->changeState(state);
        }


    protected:
        CGameState(){}
        vector<Texture> textures;
        vector<Button> buttons;
};

Texture::render 和 Texture::loadFromFile() 来自 gameengine.cpp: Texture有以下成员:

  • SDL_Texture* mTexture;
  • SDL_Point mPosition;
  • int mWidth;
  • int mHeight;
void Texture::render(SDL_Renderer* renderer,SDL_Rect* clip,double angle,SDL_Point* center,SDL_RendererFlip flip) {
    //Set rendering space to what we are rendering.
    SDL_Rect renderQuad = {mPosition.x,mPosition.y,mWidth,mHeight};

    //If there is a clip,clip the render
    if(clip!=NULL) {
        renderQuad.w = clip->w;
        renderQuad.h = clip->h;
    }

    //Render to the screen
    SDL_RendercopyEx(renderer,mTexture,clip,&renderQuad,angle,center,flip);
}

bool Texture::loadFromFile(std::string path,SDL_Renderer* rendertarget) {
    //Get rid of existing texture
    free();

    SDL_Texture* newTexture = NULL;

    SDL_Surface* loadedSurface = IMG_Load(path.c_str());
    if(loadedSurface == NULL) {
        LOG_F(ERROR,"Unable to load image %s! SDL_image Error: %s",path.c_str(),IMG_GetError());
    }
    else {
        //Create a texture from the surface pixels
        newTexture = SDL_CreateTextureFromSurface(rendertarget,loadedSurface);
        if(newTexture == NULL) {
            LOG_F(ERROR,"Unable to create texture from% s!SDL Error : % s",SDL_GetError());
        }
        else {
            mWidth = loadedSurface->w;
            mHeight = loadedSurface->h;
        }
        //Free the unused surface
        SDL_FreeSurface(loadedSurface);
    }
    mTexture = newTexture;
    return mTexture != NULL;
}

按钮类,不包括一些设置/获取功能

Button::Button() {
    buttonState = false;
    buttonTexture = Texture();
    buttonAction = -1;
}

Button::~Button() {
    buttonTexture.free();
}

void Button::handleEvent(int mouseX,int mouseY) {
    bool inside = true;

    if(mouseX < buttonTexture.getPosition().x) {
        inside = false;
    }
    //Need to make sure that buttonTexture.getWidth() actually returns a non zero value
    else if(mouseX > buttonTexture.getPosition().x + buttonTexture.getWidth()) {
        inside = false;
    }
    else if(mouseY < buttonTexture.getPosition().y) {
        inside = false;
    }
    else if(mouseY > buttonTexture.getPosition().y + buttonTexture.getHeight()) {
        inside = false;
    }
    LOG_F(INFO,"Button bounds: L: %i,R: %i,T: %i,B: %i",buttonTexture.getPosition().x,buttonTexture.getPosition().x + buttonTexture.getWidth(),buttonTexture.getPosition().y,buttonTexture.getPosition().y + buttonTexture.getHeight());
    LOG_F(INFO,"position x: %i,position y: %i,width: %i,height: %i",buttonTexture.getWidth(),buttonTexture.getHeight());
    if(!inside) {
        buttonState = false;
    }
    else {
        LOG_F(INFO,"Inside Button");
        buttonState = true;
    }
}

bool Button::getState() {
    return buttonState;
}

void Button::setState(bool newState) {
    buttonState = newState;
}

void Button::setTexture(Texture desiredTexture) {
    buttonTexture = desiredTexture;
}

CIntroState.h:

class CIntroState:public CGameState {
    public:
        void init(CGameEngine* game);
        void cleanup();

        void pause();
        void resume();

        void handleEvents(CGameEngine* game);
        void update(CGameEngine* game);
        void draw(CGameEngine* game);

        static CIntroState* instance() {
            return &mIntroState;
        }
    protected:
        CIntroState(){}
    private:
        static CIntroState mIntroState;
};

CIntroState::draw from introstate.cpp:

void CIntroState::draw(CGameEngine *game) {
    SDL_SetRenderDrawColor(game->renderer,0xFF,0xFF);
    SDL_RenderClear(game->renderer);
    Texture tempTexture;

    for(int i = 0; i < NUM_TEXTURES_FOR_STATE; i++) {
        //iterate through vector and call render method
        textures[i].render(game->renderer);
        LOG_F(INFO,"Rendering background at: x: %i,y: %i",textures[i].getPosition().x,textures[i].getPosition().y);
    }

    for(int i = 0; i < NUM_BUTTONS; i++) {
        //Iterate through the textures of the buttons and render them
        tempTexture = Texture();
        tempTexture = buttons[i].getTexture();
        tempTexture.render(game->renderer);
        LOG_F(INFO,"Rendering button at: x: %i,tempTexture.getPosition().x,tempTexture.getPosition().y);
        //tempTexture.free();
    }

    LOG_F(INFO,"Rendering to screen");
    SDL_RenderPresent(game->renderer);
}

我希望纹理会按渲染顺序显示,但我要么弄错了,要么遗漏了一些东西。

解决方法

暂无找到可以解决该程序问题的有效方法,小编努力寻找整理中!

如果你已经找到好的解决方法,欢迎将解决方案带上本链接一起发送给小编。

小编邮箱:dio#foxmail.com (将#修改为@)