我目前正在为自己的个人视频游戏项目开发内部GUI,目前我已经完成了创建基本框架的工作。它由以下类组成:
GUI_Element是我将使用我的框架创建的所有GUI类的抽象基类,其子类是GUI_Panel。 GUI_Panel的子节点是GUI_Window。
GUI_Engine存储指向GUI_Element的指针,并加载要由所有GUI_Element使用的各种PNG文件。这些PNG文件存储在SpritePool中,这是一个简单的双向量,可以存储SDL_Texture和std :: string。字符串是PNG文件名。
我目前有两个PNG文件无法使用 void GUI_Window :: render()函数,“window_top”和“window_bottom”中的以下代码正确呈现。这些16x16文件是用于渲染窗口顶部和底部边框的图块;然而,它们是唯一两个无法正确渲染的纹理。
这是GUI_Element的代码:
/*
Class: GUI_Element
Purpose: -To provide an ABSTRACT base class for all the GUI elements within the framework.
Notes: >The class already holds basic functions for hot, cold, select, and deslect.
Function pointers are going to use to provide callback/like functionality.
*/
#ifndef GUI_ELEMENT_H
#define GUI_ELEMENT_H
#include "globalvar.h"
#include "Input.h"
#include "SpritePool.h"
class GUI_Element
{
public:
GUI_Element() {}
GUI_Element(SpritePool gui_skin, int x, int y, int w, int h, bool visible, GUI_Element* parent);
virtual ~GUI_Element();
//set functions
void set_texture_ptr(SDL_Texture** texture) {texture_ptr = texture;}
void set_parent_element(GUI_Element* parent);
void set_frame(int x, int y, int w, int h);
void set_offset_x(int i) {offset_x = i;}
void set_offset_y(int i) {offset_y = i;}
void set_x(int i) {frame.x = i;}
void set_y(int i) {frame.y = i;}
void set_w(int i) {frame.w = i;}
void set_h(int i) {frame.h = i;}
void set_visible(bool b);
void set_hot(bool b);
void set_selected(bool b);
//get functions
SDL_Texture** get_texture_ptr() {return texture_ptr;}
GUI_Element* get_parent_element() {return parent_element;}
SDL_Rect* get_frame() {return &frame;}
int get_offset_x() {return offset_x;}
int get_offset_y() {return offset_y;}
int get_x() {return frame.x;}
int get_y() {return frame.y;}
int get_w() {return frame.w;}
int get_h() {return frame.h;}
//is_property functions
bool is_visible() {return visible;}
bool is_hot() {return hot;}
bool is_selected() {return selected;}
//on_action functions
virtual void on_hot() = 0;
virtual void on_cold() = 0;
virtual void on_select() = 0;
virtual void on_deselect() = 0;
//render/update/check input functions
virtual void render() = 0;
virtual void update() = 0;
virtual void check(Input &input) = 0;
protected:
int offset_x, offset_y;
SDL_Texture** texture_ptr;
GUI_Element* parent_element;
SDL_Rect frame;
bool visible;
bool hot;
bool selected;
void (*func_hot) ();
void (*func_select) ();
void (*func_cold) ();
void (*func_deselect) ();
private:
};
这是GUI_Window的代码:
#ifndef GUI_WINDOW_H
#define GUI_WINDOW_H
#include "GUI_Panel.h"
class GUI_Window : public GUI_Panel
{
public:
GUI_Window(SpritePool gui_skin, int x, int y, int w, int h, bool visible, std::string str);
virtual ~GUI_Window();
void set_name(std::string str) {name = str;}
void set_menubar_properties(bool minimize, bool pin, bool exit);
void set_border_visible(bool b);
void set_bg_visible(bool b);
std::string get_name() {return name;}
bool get_minimize_visible() {return minimize_visible;}
bool get_pin_visible() {return pin_visible;}
bool get_exit_visible() {return exit_visible;}
bool get_border_visible() {return border_visible;}
bool get_bg_visible() {return bg_visible;}
virtual void on_hot();
virtual void on_cold();
virtual void on_select();
virtual void on_deselect();
//render/update/check input functions
virtual void render();
virtual void update();
virtual void check(Input &input);
protected:
std::string name;
bool minimize_visible;
bool pin_visible;
bool exit_visible;
bool border_visible;
bool bg_visible;
SDL_Rect tile_frame;
SDL_Texture** window_top;
SDL_Texture** window_bottom;
SDL_Texture** window_left;
SDL_Texture** window_right;
SDL_Texture** window_topleft;
SDL_Texture** window_topright;
SDL_Texture** window_bottomleft;
SDL_Texture** window_bottomright;
SDL_Texture** window_minimize;
SDL_Texture** window_pin;
SDL_Texture** window_exit;
SDL_Texture** gui_bg;
private:
};
#endif // GUI_WINDOW_H
这里是GUI_Window :: render()的代码:
void GUI_Window::render()
{
if (visible)
{
if (bg_visible)
{
SDL_RenderCopy(g_renderer, *gui_bg, NULL, &frame);
}
if (border_visible)
{
tile_frame.x = frame.x;
tile_frame.y = frame.y;
tile_frame.w = 16;
tile_frame.h = 16;
SDL_RenderCopy(g_renderer, *window_topleft, NULL, &tile_frame);
tile_frame.y = frame.y;
while (tile_frame.x < (frame.x + frame.w - 32))
{
SDL_RenderCopy(g_renderer, *window_top, NULL, &tile_frame);
tile_frame.x += 16;
}
tile_frame.x += 16;
SDL_RenderCopy(g_renderer, *window_topright, NULL, &tile_frame);
if (window_top == NULL)
std::cout << "oh well" << std::endl;
while (tile_frame.y < (frame.y + frame.h - 16))
{
tile_frame.y += 16;
SDL_RenderCopy(g_renderer, *window_right, NULL, &tile_frame);
}
SDL_RenderCopy(g_renderer, *window_bottomright, NULL, &tile_frame);
while (tile_frame.x > frame.x + 16)
{
tile_frame.x -= 16;
SDL_RenderCopy(g_renderer, *window_bottom, NULL, &tile_frame);
}
tile_frame.x -= 16;
SDL_RenderCopy(g_renderer, *window_bottomleft, NULL, &tile_frame);
while (tile_frame.y > frame.y + 16)
{
tile_frame.y -= 16;
SDL_RenderCopy(g_renderer, *window_left, NULL, &tile_frame);
}
}
if (exit_visible)
{
tile_frame.x = frame.x + frame.w - 16;
tile_frame.y = frame.y;
SDL_RenderCopy(g_renderer, *window_exit, NULL, &tile_frame);
}
if (pin_visible)
{
tile_frame.x = frame.x + frame.w - 32;
tile_frame.y = frame.y;
SDL_RenderCopy(g_renderer, *window_pin, NULL, &tile_frame);
}
if (minimize_visible)
{
tile_frame.x = frame.x + frame.w - 48;
tile_frame.y = frame.y;
SDL_RenderCopy(g_renderer, *window_minimize, NULL, &tile_frame);
}
}
}
我检查了以下内容:
注意:
SDL_Texture **名称与PNG文件完全相同。
这是它的样子:
编辑:这是我的SpritePool类中的纹理加载代码:
void SpritePool::load_texture(std::string path)
{
SDL_Texture* loaded_texture = NULL;
SDL_Surface* loaded_surface = NULL;
loaded_surface = IMG_Load(path.c_str());
if (loaded_surface == NULL)
std::cout << path << " unable to be loaded!" << std::endl;
else
{
loaded_texture = SDL_CreateTextureFromSurface(g_renderer, loaded_surface);
if (loaded_texture == NULL)
std::cout << path << " unable to be converted to SDL_Texture*!" << std::endl;
else
std::cout << path << " loaded!" << std::endl;
}
SDL_FreeSurface(loaded_surface);
texture_pool.push_back(loaded_texture);
texture_names.push_back(path);
}
有人请帮助我!
答案 0 :(得分:0)
查看我的代码后,通过将SDL_Texture **转换为SDL_Texture *来解决问题。
编辑:经过大约一年的编程,我现在可以说这个问题的错误在于我使用带有std :: vector的SDL_Texture **。虽然我的矢量只有常规指针,但我发出了双指针。但是,当std :: vector调整自身大小时,它会将其内部结构复制到内存中的另一个空间,使双指针无效。