1

Program's purpose: This program's purpose it to create a basic 2d game using only the consol. The program currently only creates a moveable box with the keys "wasd". I'm planning to incorperate bullets, enemy NPC's, barriers, and much more.

Problem: Hello, for some reason my bullet constructor class in my "Bullet.cpp" file is showing up with the error "error C2512: 'BoxClass': no appropriate default constructor available". In "Bullet.h" I have "class Bullet : protected BoxClass". Why am I getting this error?

Other Question(s): Also how should I group my headers? They're getting to become a large cluster.

Comments: I also realize my game loops shouldn't be in the "BoxClass.cpp". I'm going to fix that after I get my bullet class working. If I'm structuring anything else wrong or if you see an easier way of writing some of the same code just let me know.

This is my first graphical game in c++!

ConsolApplication1.cpp:

#include "stdafx.h"
#include <windows.h>
#include "BoxClass.h"
#include "ConsolWindow.h"
#include "Bullet.h"
#include <iostream>

using namespace std;

#define W_KEY 0x57
#define S_KEY 0x53
#define A_KEY 0x41
#define D_KEY 0x44
#define R_KEY 0x52

int main() {
    //variable declaration/definition
    int right_Wall, speed_Var;

    //Consol Size/Position
    int half_screen_Size = (GetSystemMetrics(SM_CXSCREEN)/2);
    Set_Consol_Size(half_screen_Size, GetSystemMetrics(SM_CYSCREEN));
    Position_Consol(-6, 0);

    while (1) {
        cout << "Enter speed of rectangle/box\nSpeed = ";
        cin >> speed_Var;

        BoxClass box1(4, 3);
        box1.Print_Solid_Rectangle();

        cout << "\n\nMove the rectangle with wasd\n\n";


        //Rectangle Movement
        box1.Rectangle_Movement(speed_Var);
    }
    //exit
    return 0;
}

BoxClass.cpp:

#include "stdafx.h"
#include "BoxClass.h"
#include "ConsolWindow.h"
#include <iostream>
#include <math.h>
#include <Windows.h>
using namespace std;

#define W_KEY 0x57
#define S_KEY 0x53
#define A_KEY 0x41
#define D_KEY 0x44
#define R_KEY 0x52

#define _NOT_MOVING 0
#define _MOVING 1

    //Non Moving Rectangle
    void BoxClass::Print_Solid_Rectangle() {
        //calc
        boxSpacesWidth = (3 * recWidth) - 4;

        //draw top of box
        for (width = 1; width < recWidth; width += 1) {
            cout << "...";
        }
        cout << "\n";

        //draw sides
        for (height = 1; height < recHeight; height += 1) {
            cout << ":";
            height_Count++;

            for (width = 1; width < boxSpacesWidth; width += 1) {
                cout << " ";
            }

            cout << ":\n";
        }

        //draw bottom
        cout << ":";

        for (width = 1; width < boxSpacesWidth; width += 1) {
            cout << ".";
        }
        cout << ":\n";
    }

    //Moving Rectangle
    void BoxClass::Print_Rectangle_Moving(int x, int y, int horizontalSpaces, int verticleSpaces) {
        //calc
        boxSpacesWidth = (3 * x) - 4;
        rightWall = ((x-1)*3) + horizontalSpaces;
        retrieveX = (ceil((((x-1)*3)/2))+1)+horizontalSpaces;
        retrieveY = verticleSpaces;
        cout << retrieveY<<endl;

        //New Line
        for (i = 1; i <= verticleSpaces; i += 1) {
            cout << "\n";
        }

        //draw top of box
        for (width = 1; width <= horizontalSpaces; width+=1) {
            cout << " ";
        }

        for (width = 1; width < x; width += 1) {
            cout << "...";
        }
        cout << "\n";

        //draw sides
        for (height = 1; height < y; height += 1) {

            for (width = 1; width <= horizontalSpaces; width += 1) {
                cout << " ";
            }

            cout << ":";
            height_Count++;

            for (width = 1; width < boxSpacesWidth; width += 1) {
                cout << " ";
            }

            cout << ":\n";
        }

        //draw bottom
        for (width = 1; width <= horizontalSpaces; width += 1) {
            cout << " ";
        }

        cout << ":";

        for (width = 1; width < boxSpacesWidth; width += 1) {
            cout << ".";
        }
        cout << ":\n";
    }

    void BoxClass::Rectangle_Movement(int speed) {
        speed_Var = speed;

        //Rectangle Movement
        while (GetAsyncKeyState(VK_ESCAPE) == false) {

            if (GetAsyncKeyState(R_KEY)) {
                system("CLS");
                break;
            }

            if (GetAsyncKeyState(W_KEY)) {
                if (verticleCount > 0) {
                    system("CLS");
                    verticleCount = verticleCount - speed_Var;
                    Print_Rectangle_Moving(recWidth, recHeight, horizontalCount, verticleCount);
                }
            }

            if (GetAsyncKeyState(S_KEY)) {
                system("CLS");
                verticleCount = verticleCount + speed_Var;
                Print_Rectangle_Moving(recWidth, recHeight, horizontalCount, verticleCount);
            }

            if (GetAsyncKeyState(A_KEY)) {
                if (horizontalCount > 0) {
                    system("CLS");
                    horizontalCount = horizontalCount - (speed_Var*2);
                    Print_Rectangle_Moving(recWidth, recHeight, horizontalCount, verticleCount);
                }
            }

            if (GetAsyncKeyState(D_KEY)) {
                if (rightWall < 113) {
                    system("CLS");
                    horizontalCount = horizontalCount + (speed_Var*2);
                    Print_Rectangle_Moving(recWidth, recHeight, horizontalCount, verticleCount);
                }
            }

            if (GetAsyncKeyState(VK_SPACE)) {

            }
        }
    }

    // constructor
    BoxClass::BoxClass(int x, int y) {

        //variable definition
        height_Count = 1;

        speed_Var = 1;
        horizontalCount = 0; 
        verticleCount = 0;

        recWidth = x;
        recHeight = y;
    };  

BoxClass.h:

#ifndef BOXCLASS_H
#define BOXCLASS_H


class BoxClass {
    unsigned short int width;
    int height, i, recWidth, recHeight, rightWall;
    float boxSpacesWidth, height_Count;

    int width_Var, height_Var, position_Var;
    int speed_Var = 1;
    unsigned short int horizontalCount = 0, verticleCount = 0;


protected:
    //retrieve values for bullet spawn location
    int retrieveX, retrieveY;

public:
    void Print_Rectangle_Moving(int x, int y, int horizontalSpaces, int verticleSpaces);

    void Print_Solid_Rectangle();

    void Rectangle_Movement(int speed);

    // constructor
    BoxClass(int x, int y);
};

#endif

Bullet.cpp:

#include "stdafx.h"
#include "Bullet.h"
#include <iostream>
#include <Windows.h>

using namespace std;

void Bullet::Bullet_Draw_Collision() {

    for (int height = 1; height <= 2; height+=1) {
        cout << "|\n";
    }

}



Bullet::Bullet() {
}

Bullet.h:

#ifndef BULLET_H
#define BULLET_H

#include "BoxClass.h"

class Bullet : public BoxClass {

public:
    void Bullet_Draw_Collision();

    //constructor
    Bullet();

};
#endif

ConsolWindow.cpp:

#include "stdafx.h"
#include "ConsolWindow.h"
#include <iostream>
#include <Windows.h>
using namespace std;

int Find_Consol_Size() {
    CONSOLE_SCREEN_BUFFER_INFO csbi;
    int columns, rows;

    GetConsoleScreenBufferInfo(GetStdHandle(STD_OUTPUT_HANDLE), &csbi);
    columns = csbi.srWindow.Right - csbi.srWindow.Left + 1;
    rows = csbi.srWindow.Bottom - csbi.srWindow.Top + 1;

    return columns;
}

void Set_Consol_Size(int x, int y) {
    HWND console = GetConsoleWindow();
    RECT r;
    GetWindowRect(console, &r);
    MoveWindow(console, r.left, r.top, x, y, TRUE);
}

void Position_Consol(int x, int y) {
    HWND consoleWindow = GetConsoleWindow();
    SetWindowPos(consoleWindow, 0, x, y, 0, 0, SWP_NOSIZE | SWP_NOZORDER);
}

ConsolWindow.h:

#ifndef CONSOLWINDOW_H
#define CONSOLWINDOW_H

int Find_Consol_Size();
void Set_Consol_Size(int x, int y);
void Position_Consol(int x, int y);

#endif

1 Answers1

0

In c++, constructing a derived type implies that both the base and derived portions of the object must be constructed. This is done by calling the base's constructor before the derived type's constructor can begin.

The default behavior is to use the base's default constructor. However you can indicate a different base constructor to use by adding it to the member initialization list and providing appropriate arguments for it.

In your case, notice that a BoxClass only has one constructor which must be provided with an x and y, but a Bullet has no such construction argument. Perhaps some default values such as zeroes or ones might be appropriate, though I suspect you will want to add those arguments to your Bullet class. Here are a few example to illustrate how you could solve the problem.

By asking for construction arguments for Bullet :

class Bullet : public BoxClass 
{
public:
    //constructor
    Bullet(int x, int y);

};

Bullet::Bullet(int x, int y) : 
    BoxClass(x, y) // Indicates which BoxClass constructor to use
{}

By providing arbitrary construction arguments to BoxClass :

class Bullet : public BoxClass 
{
public:
    //constructor
    Bullet();

};

Bullet::Bullet() : 
    BoxClass(1, 1)
{}

Or by adding a default constructor to BoxClass, such as by giving a default value to each of it's existing constructor's arguments :

class BoxClass 
{ 
public:
    // This constructor is now a default constructor
    BoxClass(int x = 1, int y = 1);
};

class Bullet : public BoxClass 
{
public:
    //constructor
    Bullet();

};

Bullet::Bullet() // Uses the default BoxClass constructor
{}

Which solution is best depends on your design goals, but I suspect the first one is likely to be more appropriate.

François Andrieux
  • 28,148
  • 6
  • 56
  • 87