问题描述
我正在使用 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 (将#修改为@)