Allegro 5绘图到缓冲区

Allegro 5 drawing to buffer

本文关键字:缓冲区 绘图 Allegro      更新时间:2023-10-16

我正在制作一个程序,该程序将绘制屏幕上弹跳的球。我目前正在研究吸引球的部分。

我的代码包括以下内容:

  1. Ballengine类 - 管理所有Allegro功能/对象
  2. Ballmanager班 - 管理所有球
  3. 球类 - 保留有关球的信息
  4. main.cpp-游戏循环等

ballengine.h:

#pragma once
#include <allegro5allegro.h>
#include <allegro5allegro_font.h>
#include <allegro5allegro_ttf.h>
#include "BallManager.h"

ALLEGRO_DISPLAY *display;
class BallEngine
{
private:
    bool fullScreen;
    int fps;
    bool running;
public:
    BallManager BManager;
    bool getFullScreen();
    bool getIsRunning();
    void updateFullScreen();
    void setFullScreen(bool value);
    void setIsRunning(bool value);
    int getFPS();
    //Allegro Objects
    ALLEGRO_FONT *deafault_font_12;
    ALLEGRO_EVENT_QUEUE *event_queue;
    ALLEGRO_TIMER *timer;

    //Colors
    ALLEGRO_COLOR RED;
    ALLEGRO_COLOR GREEN;
    ALLEGRO_COLOR BLUE;
    ALLEGRO_COLOR YELLOW;
    ALLEGRO_COLOR PINK;
    ALLEGRO_COLOR LIGHT_BLUE;
    ALLEGRO_COLOR WHITE;
    ALLEGRO_COLOR BLACK;
    //Debug
    bool showDebug;
    void drawBallInfo(int x, int y, int id); //Draws information about a certain ball
    BallEngine(int width, int height);
    ~BallEngine(void);
};

ballengine.cpp:

#include "BallEngine.h"
BallEngine::BallEngine(int width, int height)
{
    running = true;
    showDebug = false;
    fps = 60;
    al_init();
    if(!al_init())
    {
        printf("Failed to initalize Allegro n");
    }
    al_install_keyboard();
    if(!al_install_keyboard())
    {
        printf("Failed to initalize keyboard n");
    }
    al_init_font_addon();
    al_init_ttf_addon();
    fullScreen = false;
    updateFullScreen();

    deafault_font_12 = al_load_font("arial.ttf", 12, 0);
    event_queue = al_create_event_queue();
    al_register_event_source(event_queue, al_get_keyboard_event_source());
    timer = al_create_timer(1.0/fps);
    al_register_event_source(event_queue, al_get_timer_event_source(timer));
    display = al_create_display(width, height);

    //Define engine colors
    RED = al_map_rgb(255,0,0);
    GREEN = al_map_rgb(0,255,0);
    BLUE = al_map_rgb(0,0,255);
    YELLOW = al_map_rgb(255,255,0);
    PINK = al_map_rgb(255,0,255);
    LIGHT_BLUE = al_map_rgb(255,255,0);
    WHITE = al_map_rgb(255,255,255);
    BLACK = al_map_rgb(0,0,0);
}

BallEngine::~BallEngine(void)
{
}
bool BallEngine::getFullScreen()
{
    return fullScreen;
}
bool BallEngine::getIsRunning()
{
    return running;
}
void BallEngine::updateFullScreen()
{
    if ( fullScreen == true )   
    {
        al_set_new_display_flags(ALLEGRO_FULLSCREEN);
    }
    else
    {
        al_set_new_display_flags(ALLEGRO_WINDOWED);
    }
}
void BallEngine::setFullScreen(bool value)
{
    fullScreen = value;
}
int BallEngine::getFPS()
{
    return fps;
}
void BallEngine::drawBallInfo(int x, int y, int id)
{
    if(BManager.isBallExist(id))
    {
        al_draw_textf(deafault_font_12, RED, x, y, 0, "X: %i Y: %i Velocity: %i Angle: %i Radius: %i Color %ALLEGRO_COLOR ", BManager.getBall_X(id), BManager.getBall_Y(id), BManager.getBall_Velocity(id), BManager.getBall_Angle(id), BManager.getBall_Radius(id), BManager.getBall_Color(id));
    }
    else
    {
        printf("Failed to draw ball %i information: Ball selceted out of range n", id);
    }
}

ballmanager.h:

#pragma once
#include <iostream>
#include <vector>
#include "Ball.h"
#include <allegro5allegro.h>
class BallManager
{
private:
    std::vector<Ball*> List;
public:
    //Get functions
    int getBall_X(int id);
    int getBall_Y(int id);
    int getBall_Velocity(int id);
    int getBall_Angle(int id);
    int getBall_Radius(int id);
    ALLEGRO_COLOR getBall_Color(int id);
    //Set Functions
    void setBall_X(int id, int value);
    void setBall_Y(int id, int value);
    void setBall_Velocity(int id, int value);
    void setBall_Angle(int id, int value);
    void setBall_Radius(int id, int value);
    void setBall_Color(int id, ALLEGRO_COLOR value);
    bool isBallExist(int id); //Returns true if a ball at index id exists. Else returns false.
    void CreateBall(int x, int y, int velocity, int angle, int radius, ALLEGRO_COLOR color);
    void DeleteBall(int id);
    void drawBall(int id);
    void drawBalls();
    void updateBalls(); //NOT YET DONE
    BallManager(void);
    ~BallManager(void);
};

ballmanager.cpp:

#include "BallManager.h"

BallManager::BallManager(void)
{
}

BallManager::~BallManager(void)
{
}
//Get Functions:
int BallManager::getBall_X(int id)
{
    return List[id]->getPos_X();
}
int BallManager::getBall_Y(int id)
{
    return List[id]->getPos_Y();
}
int BallManager::getBall_Velocity(int id)
{
    return List[id]->getVelocity();
}
int BallManager::getBall_Angle(int id)
{
    return List[id]->getAngle();
}
int BallManager::getBall_Radius(int id)
{
    return List[id]->getRadius();
}
ALLEGRO_COLOR BallManager::getBall_Color(int id)
{
    return List[id]->getColor();
}
//Set functions:
void BallManager::setBall_X(int id, int value)
{
    List[id]->setPos_X(value);
}
void BallManager::setBall_Y(int id, int value)
{
    List[id]->setPos_Y(value);
}
void BallManager::setBall_Velocity(int id, int value)
{
    List[id]->setVelocity(value);
}
void BallManager::setBall_Angle(int id, int value)
{
    List[id]->setAngle(value);
}
void BallManager::setBall_Radius(int id, int value)
{
    List[id]->setRadius(value);
}
void BallManager::setBall_Color(int id, ALLEGRO_COLOR value)
{
    List[id]->setColor(value);
}

void BallManager::CreateBall(int x, int y, int velocity, int angle, int radius, ALLEGRO_COLOR color)
{
    Ball* ball = new Ball(x, y, velocity, angle, radius, color);
    List.push_back(ball);
}
void BallManager::DeleteBall(int id) 
{
    if(isBallExist(id))
    {
        delete List[id];
        List.erase(List.begin()+id);
    }
    else 
    {
        printf("Failed to delete ball %i information: Ball selceted out of range n", id);
    }
}
bool BallManager::isBallExist(int id)
{
    if((id+1) > List.size() || id < 0)
    {
        return false;
    }
    return true;
}
void BallManager::drawBall(int id)
{
    List[id]->Draw();
}
void BallManager::drawBalls()
{
    int total = List.size();
    for(int index = 0; index < total; index++)
    {
        List[index]->Draw();
    }
}
void updateBalls()
{
    //TODO
}

ball.h:

#pragma once
#include <allegro5allegro.h>
#include <allegro5allegro_primitives.h>
class Ball
{
private:    
    int x;
    int y;
    int velocity; //Positive is left side of screen, Negitive is right side of screen
    int angle; // Angle derived from the positive vertical
    int radius;
    ALLEGRO_COLOR color;
public:
    //Get Functions
    int getPos_X();
    int getPos_Y();
    int getVelocity();
    int getAngle();
    int getRadius();
    ALLEGRO_COLOR getColor();
    //Set Functions
    void setPos_X(int value);
    void setPos_Y(int value);
    void setVelocity(int value);
    void setAngle(int value);
    void setRadius(int value);
    void setColor(ALLEGRO_COLOR value);
    //Draws to screen
    void Draw();

    //Constructor
    Ball(int Start_X, int Start_Y, int Start_Velocity, int Start_Angle, int Start_Radius, ALLEGRO_COLOR Start_Color);
    //Desctructor
    ~Ball(void);
};

ball.cpp:

#include "Ball.h"

Ball::Ball(int Start_X, int Start_Y, int Start_Velocity, int Start_Angle, int Start_Radius, ALLEGRO_COLOR Start_Color)
{
    x = Start_X;
    y = Start_Y;
    velocity = Start_Velocity;
    angle = Start_Angle;
    radius = Start_Radius;
    color = Start_Color;
}

Ball::~Ball(void)
{
}
//Get functions
int Ball::getPos_X()
{
    return x;
}
int Ball::getPos_Y()
{
    return y;
}
int Ball::getVelocity()
{
    return velocity;
}
int Ball::getAngle()
{
    return angle;
}
int Ball::getRadius()
{
    return radius;
}
ALLEGRO_COLOR Ball::getColor()
{
    return color;
}

//Set functions
void Ball::setPos_X(int value)
{
    x = value;
}
void Ball::setPos_Y(int value)
{
    y = value;
}
void Ball::setVelocity(int value)
{
    velocity = value;
}
void Ball::setAngle(int value)
{
    angle = value;
}
void Ball::setRadius(int value)
{
    radius = value;
}
void Ball::setColor(ALLEGRO_COLOR value)
{
    color = value;
}
void Ball::Draw()
{
    al_draw_filled_circle(x, y, radius, color);
}

main.cpp:

#include <allegro5allegro.h>
#include "BallEngine.h"
int ScreenWidth = 620;
int ScreenHeight = 480;

int main()
{
    BallEngine Engine(ScreenWidth, ScreenHeight);
    //Test balls
    Engine.BManager.CreateBall(10, 20, 0, 0, 5, al_map_rgb(0,0,255));
    Engine.BManager.CreateBall(11, 21, 1, 1, 5, al_map_rgb(0,0,255));
    Engine.BManager.CreateBall(12, 22, 2, 2, 5, al_map_rgb(0,0,255));
    Engine.BManager.CreateBall(13, 23, 3, 3, 5, al_map_rgb(0,0,255));

    ALLEGRO_EVENT events;
    int selected = 0; //Used to show which ball is selected

    al_start_timer(Engine.timer);
    while(Engine.getIsRunning())
    {
        al_wait_for_event(Engine.event_queue, &events);
        if(events.type == ALLEGRO_EVENT_KEY_DOWN)
        {
            //Keyboard Input
            switch(events.keyboard.keycode)
            {
                case ALLEGRO_KEY_ESCAPE:
                    Engine.setIsRunning(false);
                    break;
                case ALLEGRO_KEY_RIGHT:
                    Engine.showDebug = !Engine.showDebug; //Toggles the selected balls info
                    break;
                case ALLEGRO_KEY_UP:
                    selected++;
                    break;
                case ALLEGRO_KEY_DOWN:
                    selected--;
                    break;
                case ALLEGRO_KEY_DELETE:
                    Engine.BManager.DeleteBall(selected); //Deletes a certain ball
                    break;
            }
        }
        else if(events.type == ALLEGRO_EVENT_TIMER)
        {
            //Update
        }
        //Draw
        Engine.BManager.drawBalls();
        //Show debug
        if(Engine.showDebug == true)
        {
            Engine.drawBallInfo(10, 10, selected);
        }
        al_flip_display();
        al_clear_to_color(al_map_rgb(0,0,0));
    }
    return 0;
}

我在吸球很难。在Allegro 4中,您将通过一个缓冲区将其拉到,然后将缓冲区绘制到屏幕上。借助我上面的代码,我会在球类中的draw()函数上遇到错误。

错误读取:调试错误!r6010 -abort()已称为

我还获得了一些信息命令提示:断言失败:addon_Initialized,文件allegro-git addons primitives primitives.c,第79行

我认为我会遇到错误,因为绘制功能没有任何地方可以绘制,因为显示器是在Ballengine类中创建的,但是我该如何修复?

断言失败:addon_Initialized,文件allegro-git addons pirinitives primitives.c,第79行

这正是问题。您尚未初始化原始插件。

al_init_primitives_addon()

另外,您应该使用前向斜线作为路径的一部分(例如<allegro5/allegro.h>),因为它是跨平台。