Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/130.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Allegro 5:在std映射中存储位图时出现问题 我开始在Visual Studio 2017中用AlelGro 5在C++中创建一个游戏。为了便于管理图像,我创建了一个ImageLoader类,该类将加载和存储所有活动图像,并根据需要销毁它们。它使用将文件名与相应图像匹配的映射来实现这一点。 当前我的主代码如下所示: int main(){ if (!al_init()) { al_show_native_message_box(NULL, NULL, NULL, "Could not intialize allegro 5.", NULL, NULL); return -1; } ALLEGRO_DISPLAY *display = al_create_display(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT); al_set_window_title(display, "Game title"); // make usre the display was created correctly if (!display) { al_show_native_message_box(display, "Title", "settings", "Could not create Allegro window.", NULL, NULL); } // intialize fonts, primitives, keyboard,etc. al_init_font_addon(); al_init_ttf_addon(); al_init_primitives_addon(); al_install_keyboard(); if(!al_init_image_addon()) { al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); return -1;} ImageLoader image_loader; ALLEGRO_BITMAP *image = al_load_bitmap(filename.c_str()); if (image == NULL) { std::cout << filename << std::endl; std::cout << "loader failed to load image" << std::endl; } image_map[filename] = image; ALLEGRO_BITMAP * ImageLoader::get_current_image(GameImage image) { auto it = image_map.find(image.get_image_filename()); if(it == image_map.end()) return nullptr; else return it->second; //return image_map[image.get_image_filename()]; }_C++_Visual Studio_Bitmap_Allegro - Fatal编程技术网

Allegro 5:在std映射中存储位图时出现问题 我开始在Visual Studio 2017中用AlelGro 5在C++中创建一个游戏。为了便于管理图像,我创建了一个ImageLoader类,该类将加载和存储所有活动图像,并根据需要销毁它们。它使用将文件名与相应图像匹配的映射来实现这一点。 当前我的主代码如下所示: int main(){ if (!al_init()) { al_show_native_message_box(NULL, NULL, NULL, "Could not intialize allegro 5.", NULL, NULL); return -1; } ALLEGRO_DISPLAY *display = al_create_display(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT); al_set_window_title(display, "Game title"); // make usre the display was created correctly if (!display) { al_show_native_message_box(display, "Title", "settings", "Could not create Allegro window.", NULL, NULL); } // intialize fonts, primitives, keyboard,etc. al_init_font_addon(); al_init_ttf_addon(); al_init_primitives_addon(); al_install_keyboard(); if(!al_init_image_addon()) { al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); return -1;} ImageLoader image_loader; ALLEGRO_BITMAP *image = al_load_bitmap(filename.c_str()); if (image == NULL) { std::cout << filename << std::endl; std::cout << "loader failed to load image" << std::endl; } image_map[filename] = image; ALLEGRO_BITMAP * ImageLoader::get_current_image(GameImage image) { auto it = image_map.find(image.get_image_filename()); if(it == image_map.end()) return nullptr; else return it->second; //return image_map[image.get_image_filename()]; }

Allegro 5:在std映射中存储位图时出现问题 我开始在Visual Studio 2017中用AlelGro 5在C++中创建一个游戏。为了便于管理图像,我创建了一个ImageLoader类,该类将加载和存储所有活动图像,并根据需要销毁它们。它使用将文件名与相应图像匹配的映射来实现这一点。 当前我的主代码如下所示: int main(){ if (!al_init()) { al_show_native_message_box(NULL, NULL, NULL, "Could not intialize allegro 5.", NULL, NULL); return -1; } ALLEGRO_DISPLAY *display = al_create_display(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT); al_set_window_title(display, "Game title"); // make usre the display was created correctly if (!display) { al_show_native_message_box(display, "Title", "settings", "Could not create Allegro window.", NULL, NULL); } // intialize fonts, primitives, keyboard,etc. al_init_font_addon(); al_init_ttf_addon(); al_init_primitives_addon(); al_install_keyboard(); if(!al_init_image_addon()) { al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!", NULL, ALLEGRO_MESSAGEBOX_ERROR); return -1;} ImageLoader image_loader; ALLEGRO_BITMAP *image = al_load_bitmap(filename.c_str()); if (image == NULL) { std::cout << filename << std::endl; std::cout << "loader failed to load image" << std::endl; } image_map[filename] = image; ALLEGRO_BITMAP * ImageLoader::get_current_image(GameImage image) { auto it = image_map.find(image.get_image_filename()); if(it == image_map.end()) return nullptr; else return it->second; //return image_map[image.get_image_filename()]; },c++,visual-studio,bitmap,allegro,C++,Visual Studio,Bitmap,Allegro,然后,ImageLoader为播放器加载图像: ALLEGRO_BITMAP *image = al_load_bitmap(filename); if (image == NULL) { std::cout << filename << std::endl; std::cout << "loader failed to load image" << std::endl; } image_map[filename] = image

然后,ImageLoader为播放器加载图像:

ALLEGRO_BITMAP *image = al_load_bitmap(filename);

if (image == NULL) {
    std::cout << filename << std::endl;
    std::cout << "loader failed to load image" << std::endl;
}
image_map[filename] = image;
我已经通过检查image\u map.findimage.get\u image\u filename==image\u map.end进行了测试,以确保我在这里使用的文件名与加载图像并将其存储在地图中时使用的文件名相同,但即使返回false,ALLEGRO\u位图指针仍然为null。我已经尝试使用映射存储位图而不是指针,但是当我尝试向映射添加元素时会出现错误,因为我不允许像这样修改映射值。为什么这些指针在我设置它们和检索它们之间会变为空?对于如何存储位图,我也愿意接受其他建议

编辑:我修改了我的项目,将作为字符数组的文件名实例更改为std::strings。图像映射现在在ImageLoader.h中声明为std::map image\u map,GameImage存储的文件名现在为std::string image\u filename。ImageLoader.cpp中的load_图像现在如下所示:

int main(){

if (!al_init()) {
    al_show_native_message_box(NULL, NULL, NULL, "Could not intialize allegro 5.", NULL, NULL);
    return -1;
}

ALLEGRO_DISPLAY *display = al_create_display(DEFAULT_SCREEN_WIDTH, DEFAULT_SCREEN_HEIGHT);
al_set_window_title(display, "Game title");

// make usre the display was created correctly
if (!display) {
    al_show_native_message_box(display, "Title", "settings", "Could not create Allegro window.", NULL, NULL);
}

// intialize fonts, primitives, keyboard,etc.
al_init_font_addon();
al_init_ttf_addon();
al_init_primitives_addon();
al_install_keyboard();
if(!al_init_image_addon()) {
al_show_native_message_box(display, "Error", "Error", "Failed to initialize al_init_image_addon!", 
                           NULL, ALLEGRO_MESSAGEBOX_ERROR);
return -1;}
ImageLoader image_loader;
ALLEGRO_BITMAP *image = al_load_bitmap(filename.c_str());

if (image == NULL) {
    std::cout << filename << std::endl;
    std::cout << "loader failed to load image" << std::endl;
}
image_map[filename] = image;
ALLEGRO_BITMAP * ImageLoader::get_current_image(GameImage image)
{
    auto it = image_map.find(image.get_image_filename());
    if(it == image_map.end()) return nullptr;
    else return it->second;
    //return image_map[image.get_image_filename()];
}
然而,同样的问题仍然存在。我还检查了图像映射的大小,在整个程序期间它一直保持为1,插入的图像的文件名作为键,值以指向位图的非空指针开始,并在某个点显示为空

编辑2:

将字符数组更改为字符串,并修复get_current_image,以便在未找到搜索的文件名时不再将其添加到映射中。之后,我发现在将图像加载到一行时也犯了一个错误,我最初发布问题时忘了将其包括在内:

current_screen.load_images(image_loader);
事实证明,我写的load_图像是这样的:

void MainGameScreen::load_images(ImageLoader loader)
…这意味着函数对loader的调用实际上并没有应用到我传入的ImageLoader。我把它改成:

void MainGameScreen::load_images(ImageLoader& loader)

…现在一切正常。

您的问题是使用const char*作为键意味着map将执行直接地址比较,即字符串的地址是否等于我在内存中保存的字符串的地址。这几乎肯定不是执行字符串比较的方式

这个问题实际上有两种解决方案,具体取决于您的用例。第一种方法是简单地将const char*更改为std::string,这是最简单的解决方案,也是默认情况下应该做的事情

std::map<std::string, ALLEGRO_BITMAP*> image_map;
这样,找不到映像不会欺骗您使用的任何调试工具,使其认为有效的空值存储在该位置

如果您想使用内置的异常功能,也可以将其简化为:

ALLEGRO_BITMAP * ImageLoader::get_current_image(GameImage image)
{
    //Will throw an exception if nothing is found
    return image_map.at(image.get_image_filename());
}

我做了此更改,但问题仍然存在。我认为filename键与我最初输入的键匹配,因为image\u map.findimage.get\u image\u filename==image\u map.end返回false,但是我调用get_current_image时的值仍然为空。@user3726962将您的修订版get_current_image添加到原始帖子中。我没有更改get_current_image,因为它不包含键的类型,但是GameImage中的get_image文件名现在返回一个字符串而不是一个字符数组。我做了您建议的更改,但我仍然遇到同样的问题。但是,我现在发现,在加载图像并将其添加到load_image中的贴图后,图像_map的大小立即为1,但在get_current_image中再次检查时,它将变为0。我不确定地图在哪里会改变大小。
ALLEGRO_BITMAP * ImageLoader::get_current_image(GameImage image)
{
    //Will throw an exception if nothing is found
    return image_map.at(image.get_image_filename());
}