简体   繁体   中英

Visual C++ and Allegro5: cannot recognize objects from abstract class from header file

I am a beginner in allegro and not really too well-seasoned with C++, but I have knowledge of the language so I wished to code a chess game. But since I wanted to use images in this game, I looked into Allegro 5 to program it. I have come up with a (not complete of course) header file to initialize every chess piece in the game:

Piece.h

#pragma once
#include <allegro5/allegro.h>
#include <allegro5/allegro_native_dialog.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include <iostream>
#include <string>

using namespace std;

class Piece
{
    private:

        int pieceX;
        int pieceY;
        bool inGame;
        char pieceColor;
        string imgAddress;
        ALLEGRO_BITMAP *pieceImage;

    public:

        Piece(int pieceX, int pieceY, bool inGame, char pieceColor, string imgAddress)
        {
            this->pieceX = pieceX;
            this->pieceY = pieceY;
            this->inGame = inGame;
            this->pieceColor = pieceColor;
            this->imgAddress = imgAddress;
            pieceImage = al_load_bitmap(imgAddress.c_str());
        }

        int getPieceX()
        {
            return pieceX;
        }

        int getPieceY()
        {
            return pieceY;
        }

        bool isInGame()
        {
            return inGame;
        }

        char getPieceColor()
        {
            return pieceColor;
        }

        string getImageAddress()
        {
            return imgAddress;
        }

        void setPieceX(int newx)
        {
            pieceX = newx;
        }

        void setPieceY(int newy)
        {
            pieceY = newy;
        }

        void setinGame(bool newingame)
        {
            inGame = newingame;
        }

        void setImageAddress(string newimgaddr)
        {
            imgAddress = newimgaddr;
        }

        void reloadImage()
        {
            pieceImage = al_load_bitmap(imgAddress.c_str());
        }

        Piece(void)
        {

        }

        ~Piece(void)
        {

        }

};

and everything else would be handled in the main class, Chess.cpp

#include <allegro5/allegro.h>
#include <allegro5/allegro_native_dialog.h>
#include <allegro5/allegro_primitives.h>
#include <allegro5/allegro_image.h>
#include "Piece.h"
#include <iostream>
#include <string>
#include <cstring>

using namespace std;

const int SIDELENGTH = 50;
const int ROWCOLSPAN = 8;
const int WINDOW_WIDTH = (SIDELENGTH * ROWCOLSPAN) + 240;
const int WINDOW_HEIGHT = (SIDELENGTH * ROWCOLSPAN) + 40; 
const float FPS = 60;
const int MAXPIECES = ROWCOLSPAN * 2;
const int MAXSPACES = ROWCOLSPAN * ROWCOLSPAN;

setupBoard(Piece [MAXPIECES], Piece [MAXPIECES], char [MAXSPACES]);

int main()
{
    ALLEGRO_DISPLAY *gameDisplay;

    if (!al_init()) cout << "Failed to load Allegro 5 for Chess++..." << endl;

    gameDisplay = al_create_display(WINDOW_WIDTH, WINDOW_HEIGHT);
    al_set_window_title(gameDisplay, "Chess++");

    if (!gameDisplay) cout << "Couldn't create Allegro 5 display for Chess++..." << endl;

    al_init_primitives_addon(); //allows to load primitives
    al_install_keyboard(); //allows for keyboard use*/
    al_install_mouse(); //installs the mouse to be able to use it
    al_init_image_addon(); //prepares image loading

    ALLEGRO_EVENT_QUEUE *gameQueue = al_create_event_queue(); //queue that receives events and acts them in order
    al_register_event_source(gameQueue, al_get_keyboard_event_source()); //registers keyboard events to be recognized within event_queue

    ALLEGRO_KEYBOARD_STATE keyState;
    ALLEGRO_TIMER *gameTimer = al_create_timer(1.0 / FPS);

    al_register_event_source(gameQueue, al_get_keyboard_event_source()); //registers keyboard events to be recognized within event_queue
    al_register_event_source(gameQueue, al_get_timer_event_source(gameTimer)); //registers a timer to work within event_queue
    al_register_event_source(gameQueue, al_get_display_event_source(gameDisplay)); //registers the window to be able to give it events
    al_register_event_source(gameQueue, al_get_mouse_event_source()); //register the installed mouse

    bool gameOver = false;
    bool draw = false;
    bool quitclose = false;

    int X = 0;
    int Y = 0;

    Piece blackPieces[MAXPIECES];
    Piece whitePieces[MAXPIECES];

    //The 8 by 8 board with the pieces; lowercase for black, uppercase for white
    char chessboard[] = "rnbqkbnr\n"
                        "pppppppp\n" 
                        "--------\n"
                        "--------\n"
                        "--------\n"
                        "--------\n"
                        "--------\n"
                        "PPPPPPPP\n"
                        "RNBQKBNR";

    //setupBoard(blackPieces, whitePieces, chessboard);

    al_start_timer(gameTimer); //starts the specified timer

    gameloop:
    while(!gameOver)
    {
        ALLEGRO_EVENT gameEvents; //create receiver for events
        al_wait_for_event(gameQueue, &gameEvents); //waits for an event from event_queue to be passed on to ALLEGRO_EVENT events

        if (gameEvents.type == ALLEGRO_EVENT_KEY_UP/*DOWN*/)
        {

        }
        else if (gameEvents.type == ALLEGRO_EVENT_DISPLAY_CLOSE)
        {
            quitclose = true;
            gameOver = true;
        }
        else if (gameEvents.type == ALLEGRO_EVENT_MOUSE_AXES) //determines the movement of the mouse coordinates
        {

        }
        else if (gameEvents.type == ALLEGRO_EVENT_MOUSE_BUTTON_DOWN) //if a mouse button is pressed
        {

        }

        if (gameEvents.type == ALLEGRO_EVENT_TIMER)
        {
            draw = true;
        }

        if (draw)
        {
            draw = false;

            int squareX = 20;
            int squareY = 20;
            bool colorchange = true;
            for (int i = 1; i <= MAXSPACES;i++)
            {               
                ALLEGRO_COLOR squarecolor = al_map_rgb(255, 255, 255);
                if (!colorchange) squarecolor = al_map_rgb(0, 100, 0);

                al_draw_filled_rectangle(squareX, squareY, squareX + SIDELENGTH, squareY + SIDELENGTH, squarecolor);
                squareX += SIDELENGTH;
                if (i % ROWCOLSPAN != 0) colorchange = !colorchange;

                if (i % ROWCOLSPAN == 0)
                {
                    squareY += SIDELENGTH;
                    squareX = 20;
                }

            }

            al_flip_display();          
            al_clear_to_color(al_map_rgb(0, 0, 0)); //clears the canvas (display) like Java's repaint()
        }

    }

    if (quitclose)
    {
        int quit = al_show_native_message_box(gameDisplay, "CHES++: QUIT", "ARE YOU SURE YOU WANNA QUIT?", "Please select YES or NO", NULL, ALLEGRO_MESSAGEBOX_YES_NO);
        if (quit == 0)
        {
            gameOver = false;
            goto gameloop;
        }
    }

    al_destroy_display(gameDisplay);

    /*cin.sync();
    cout << "\n\nPress any key to finish...";
    cin.get();*/
    return 0;
}

void setupBoard(Piece bp[MAXPIECES], Piece wp[MAXPIECES], char cb[])
{
    int barrindex = 0;
    int warrindex = 0;
    int x = 20;
    int y = 20;

    for (int i = 0; i < MAXSPACES; i++)
    {
        if (cb[i] == 'r')
        {
            bp[barrindex] = new Piece(x, y, true, 'b', "images/br.png");
            barrindex++;
            x += SIDELENGTH;
        }     
        if (cb[i] == 'n')
        {
            bp[barrindex] = new Piece(x, y, true, 'b', "images/bn.png");
            barrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'b')
        {
            bp[barrindex] = new Piece(x, y, true, 'b', "images/bb.png");
            barrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'q')
        {
            bp[barrindex] = new Piece(x, y, true, 'b', "images/bq.png");
            barrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'k')
        {
            bp[barrindex] = new Piece(x, y, true, 'b', "images/bk.png");
            barrindex++;
            x += SIDELENGTH;
        } 
        if (cb[i] == 'p')
        {
            bp[barrindex] = new Piece(x, y, true, 'b', "images/bp.png");
            barrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'R')
        {
            wp[warrindex] = new Piece(x, y, true, 'w', "images/wr.png");
            warrindex++;
            x += SIDELENGTH;
        }     
        if (cb[i] == 'N')
        {
            wp[warrindex] = new Piece(x, y, true, 'w', "images/wn.png");
            warrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'B')
        {
            wp[warrindex] = new Piece(x, y, true, 'w', "images/wb.png");
            warrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'Q')
        {
            wp[warrindex] = new Piece(x, y, true, 'w', "images/wq.png");
            warrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == 'K')
        {
            wp[warrindex] = new Piece(x, y, true, 'w', "images/wk.png");
            warrindex++;
            x += SIDELENGTH;
        } 
        if (cb[i] == 'P')
        {
            wp[warrindex] = new Piece(x, y, true, 'w', "images/wp.png");
            warrindex++;
            x += SIDELENGTH;
        }
        if (cb[i] == '-')
        {
            x += SIDELENGTH;
        } 
        if (cb[i] == '\n')
        {
            y += SIDELENGTH;
            x = 20;
        }
    }
}

Before adding the setupBoard() function and the two Piece objects (blackPieces and whitePieces), my program would run, and it would display a nice "chessboard" which is basically 64 drawn squares using the allegro's primitive library, so I think I've installed the libraries and drivers correctly. Yet the errors I get are out of my reach:

  1. First, setupBoard is a void, just meant to modify other variables to organize the code. Yet Intellisense gives me an error: this declaration has no storage class or type specifier

  2. I don't get an error with #include "Piece.h" , but on the declaration of the arrays blackPieces and whitePieces, I get identifier "Piece" is undefined

  3. Inside the setupBoard function at the bottom of Chess.cpp, I read through the char array cb, which comes from chessboard, which has specific characters to place the pieces in the board. And depending on which character, a Piece object is dynamically allocated to its respective Piece array., like this:

bp[barrindex] = new Piece(x, y, true, 'b', "images/br.png");

Then integers that control the x and y of the board are incremented accordingly to draw them in different places. However, while there appears to be no error except for new Piece( , which I guess is because of error 2, I get this error:

error C2679: binary '=' : no operator found which takes a right-hand operand of type 'Piece *' (or there is no acceptable conversion)

I'm sure I must be allocating wrong, but I don't know how, I never had errors of this kind. Now, I could always try doing a chess game in Java or C# but I wanted to make some kind of game in C++ (I figure the logic to make an AI won't have anything to do with knowledge of the language). Please, if anyone knows how to solve these errors I'd be very thankful!!

setupBoard(Piece [MAXPIECES], Piece [MAXPIECES], char [MAXSPACES]);

You need a void in front of that.

These are different things:

Piece bp[MAXPIECES]
Piece* bp[MAXPIECES]

The way you have it, you need to do this:

wp[warrindex] = Piece(x, y, true, 'w', "images/wn.png");

To understand the difference between the two, read up on the stack vs heap memory allocation. You really probably want to use the heap via Piece* bp[MAXPIECES] and keeping your new calls.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM