Warning: file_get_contents(/data/phpspider/zhask/data//catemap/6/cplusplus/158.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
C++ Allegro程序显示黑屏,然后崩溃_C++_Allegro - Fatal编程技术网

C++ Allegro程序显示黑屏,然后崩溃

C++ Allegro程序显示黑屏,然后崩溃,c++,allegro,C++,Allegro,我正在学习面向对象编程和allegro库,所以我开始编写一个简单的菜单,但代码显示为黑屏,然后崩溃 对于关于类外观、用头拆分代码、代码的一般语法以及最重要的是查找代码无法解决的问题的建议,我将不胜感激 main.cpp #include "Menu.h" int main() { Menu m; return 0; } END_OF_MAIN() 菜单 #ifndef MENU_H_ #define MENU_H_ #include <allegro.h> cl

我正在学习面向对象编程和allegro库,所以我开始编写一个简单的菜单,但代码显示为黑屏,然后崩溃

对于关于类外观、用头拆分代码、代码的一般语法以及最重要的是查找代码无法解决的问题的建议,我将不胜感激

main.cpp

#include "Menu.h"

int main() {
    Menu m;
    return 0;
}
END_OF_MAIN()
菜单

#ifndef MENU_H_
#define MENU_H_
#include <allegro.h>

class Menu {
    static bool isWorking;
    static const int WIDTH = 800;
    static const int HEIGHT = 600;
public:
    Menu();
    virtual ~Menu();
};

#endif
\ifndef菜单_
#定义菜单_
#包括
班级菜单{
静态布尔正在工作;
静态常数int宽度=800;
静态常数int高度=600;
公众:
菜单();
虚拟菜单();
};
#恩迪夫
menu.cpp

#include "MenuPointer.h"
#include "Menu.h"
#include <string>
using namespace std;

bool Menu::isWorking = true;

Menu::Menu() {
    allegro_init();
    install_keyboard();
    install_timer();
    set_color_depth(8);
    set_gfx_mode(GFX_AUTODETECT_WINDOWED, WIDTH, HEIGHT, 0, 0);
    string * menuOptions = new string[2];
    menuOptions[0] = "New Game";
    menuOptions[2] = "Exit";

    // menu pointer is an object highlighting menu options

    MenuPointer menuPointer(2, 0, WIDTH, HEIGHT/2, menuOptions);
    while (isWorking) {
        menuPointer.menuInit();
        blit(menuPointer.getBuffer(), screen, 0, 0, 0, 0, WIDTH, HEIGHT);
    }
}

Menu::~Menu() {
    allegro_exit();
    clear_keybuf();
}
#包括“MenuPointer.h”
#包括“Menu.h”
#包括
使用名称空间std;
bool菜单::isWorking=true;
菜单::菜单(){
第一快板();
安装键盘();
安装计时器();
设置颜色和深度(8);
设置_gfx_模式(gfx_自动检测_窗口,宽度,高度,0,0);
字符串*菜单选项=新字符串[2];
菜单选项[0]=“新游戏”;
菜单选项[2]=“退出”;
//菜单指针是突出显示菜单选项的对象
菜单指针菜单指针(2,0,宽度,高度/2,菜单选项);
(工作时){
menuPointer.menuInit();
blit(menuPointer.getBuffer(),屏幕,0,0,0,宽度,高度);
}
}
菜单::~Menu(){
快板退出();
清除_keybuf();
}
MenuPointer.h

#ifndef MENUPOINTER_H_
#define MENUPOINTER_H_

#include <string>
#include <allegro.h>
using namespace std;

class MenuPointer {
    int pointerNumber;
    BITMAP * buffer;
    const int optionsNumber;
    const int pointerWidth;
    const int pointerHeight;
    BITMAP ** optionsImages;
    const string * optionsTexts;
    void paintPointer();
public:
    void menuInit();
    BITMAP * getBuffer();
    MenuPointer(int, int, int, int, BITMAP **);
    MenuPointer(int, int, int, int, const string *);
    virtual ~MenuPointer();
};

#endif
\ifndef菜单指针_
#定义菜单指针_
#包括
#包括
使用名称空间std;
类菜单指针{
int pointerNumber;
位图*缓冲区;
常量int选项编号;
常数int指针宽度;
常数int指针八;
位图**选项图像;
常量字符串*选项文本;
void paintPointer();
公众:
void menuInit();
位图*getBuffer();
菜单指针(int,int,int,int,int,位图**);
菜单指针(int,int,int,int,int,const string*);
虚拟~MenuPointer();
};
#恩迪夫
MenuPointer.cpp

#include "MenuPointer.h"
#include "Menu.h"
#include <string>
using namespace std;


// this constructor creates menu pointer when options are array of images
MenuPointer::MenuPointer(int i, int j, int k, int l, BITMAP ** optionsImages)
    :pointerNumber(j), optionsNumber(i), pointerWidth(k), pointerHeight(l) {
    buffer = create_bitmap(pointerWidth, pointerHeight);
    optionsTexts = NULL;
    this->optionsImages = optionsImages;
}

// this constructor creates menu pointer when options are array of text
MenuPointer::MenuPointer(int i, int j, int k, int l, const string * optionsTexts)
    :pointerNumber(j), optionsNumber(i), pointerWidth(k), pointerHeight(l) {
        buffer = create_bitmap(pointerWidth, pointerHeight);
        optionsImages = NULL;
        this->optionsTexts = optionsTexts;
}


// draws a rectangle in the range from the beginning to the next option which highlights
void MenuPointer::paintPointer() {
    rectfill(buffer, 0, pointerNumber*pointerHeight, pointerHeight, (pointerNumber+1)*pointerHeight, makecol( 128, 30, 30 ) );
}


void MenuPointer::menuInit() {
    clear_to_color(buffer, makecol( 128, 128, 128 ));
    paintPointer();
    if (optionsTexts != NULL) {
        // converts string to char array
        for (int i = 0; i < optionsNumber; ++i) {
            char *a = new char[optionsTexts[i].size()+1];
            a[optionsTexts[i].size()] = 0;
            memcpy(a, optionsTexts[i].c_str(), optionsTexts[i].size());
            textout_ex(screen, font, a, 0, i*pointerWidth, makecol(255,0,0), -1);
        }
    } else {
        // draws option image for images array
        for (int i = 0; i < optionsNumber; ++i) {
            masked_blit(optionsImages[i], screen, 0, 0, 0, i*pointerWidth, optionsImages[i]->w, optionsImages[i]->h);
        }
    }
}

BITMAP * MenuPointer::getBuffer() {
    return buffer;
}

MenuPointer::~MenuPointer() {
    destroy_bitmap(buffer);
}
#包括“MenuPointer.h”
#包括“Menu.h”
#包括
使用名称空间std;
//当选项是图像数组时,此构造函数创建菜单指针
菜单指针::菜单指针(int i、int j、int k、int l、位图**选项图像)
:指针编号(j)、选项编号(i)、指针宽度(k)、指针高度(l){
缓冲区=创建位图(指针宽度、指针高度);
选项文本=空;
此->选项图像=选项图像;
}
//当选项是文本数组时,此构造函数创建菜单指针
MenuPointer::MenuPointer(int i、int j、int k、int l、const string*选项文本)
:指针编号(j)、选项编号(i)、指针宽度(k)、指针高度(l){
缓冲区=创建位图(指针宽度、指针高度);
optionsImages=NULL;
此->选项文本=选项文本;
}
//在从开始到高亮显示的下一个选项的范围内绘制矩形
void菜单指针::paintPointer(){
rectfill(buffer,0,pointerNumber*pointerHeight,pointerHeight,(pointerNumber+1)*pointerHeight,makecol(128,30,30));
}
void MenuPointer::menuInit(){
清除颜色(缓冲区、makecol(128、128、128));
paintPointer();
如果(选项文本!=NULL){
//将字符串转换为字符数组
对于(int i=0;iw,选项图像[i]>h);
}
}
}
位图*菜单指针::getBuffer(){
返回缓冲区;
}
MenuPointer::~MenuPointer(){
销毁位图(缓冲区);
}

您有关于崩溃的更多调试信息吗

首先,可能导致崩溃的一个问题是无法访问阵列菜单选项

string * menuOptions = new string[2];
menuOptions[0] = "New Game";
menuOptions[2] = "Exit"; // THIS IS WRONG
此循环中存在泄漏:

    for (int i = 0; i < optionsNumber; ++i) {
        char *a = new char[optionsTexts[i].size()+1]; //this is never freed
        a[optionsTexts[i].size()] = 0;
        memcpy(a, optionsTexts[i].c_str(), optionsTexts[i].size());
        textout_ex(screen, font, a, 0, i*pointerWidth, makecol(255,0,0), -1);
    }
for(int i=0;i
各种提示:

  • 使用strncpy而不是memcpy复制字符串
  • 方法/函数参数的名称必须更加清晰。(切勿使用i、j、k)
  • 我总是喜欢在方法/函数声明上加上名字
  • 将循环方法移出构造函数。(名为update的方法可以正常使用)

  • 始终检查返回值!尤其是当事情开始崩溃的时候

    您已要求Allegro以8位颜色深度运行。这可能会失败,即使在32位系统上请求24位也可能失败。您可以使用desktop\u color\u depth()查找主机正在运行的内容

    确保set_gfx_mode()在继续之前不会返回错误,并且所有位图都已实际加载。(not==null)