I am working on recreating pong, and while moving drawPaddle function from the main Game class to the Paddle class I ran into an issue where the function cannot read the member variables (even though they are in the same class). The class is in a header file and the function definitions are in a cpp file. The variables in question are height, width, xPos, and yPos.
Paddle class
#include "Graphics.h"
class Paddle
{
public:
void setX(int z)
{
xPos = z;
}
int getX()
{
return xPos;
}
void setY(int z)
{
yPos = z;
}
int getY()
{
return yPos;
}
int getWidth() {
return width;
}
void setHeight(int z)
{
height = z;
}
int getHeight()
{
return height;
}
void setPlayer(bool z)
{
player = z;
}
bool getPlayer()
{
return player;
}
private:
//functions
void drawPaddle(Graphics& gfx);
void updatePaddle(Graphics& gfx);
//variables
int xPos;
int yPos = Graphics::ScreenHeight / 2 - Paddle::height / 2;
bool player;
static constexpr int width = 20;
int height = 100;
};
drawPaddle function
#include "Paddle.h"
#include "Graphics.h"
void drawPaddle(Graphics gfx)
{
for (int i = 0; i < width; i++)
{
for (int j = 0; j < Paddle::height; j++)
{
gfx.PutPixel(p.getX() + i, p.getY() + j, Colors::White);
}
}
}
As you can see I've tried accessing it with the raw variable (tells me the variable is undefined), through the class (tells me the variable is inaccessible), and using the getter for it (failed because it must be in reference to a specific instance). Anyone have any idea what I am doing wrong? Thanks.
In the definition, you didn't indicate that drawPaddle was a member of Paddle, so it was treating that definition as a definition of a free function, not a member function. Free functions wouldn't have access to the private members.
It should start with
void Paddle::drawPaddle(Graphics gfx)
Related
I am using an SDL Template and I am trying to implement gravity into my code so I am trying to set a Y as the strength of my gravity in update but when I try to use a pointer to setY I always get an error "a pointer to a bound function may only be used to call the function using a setter" the code below is from my GameScene.cpp
#include "GameScene.h"
GameScene::GameScene()
{
// Register and add game objects on constructor
player = new Player();
this->addGameObject(player);
floor = new Floor();
this->addGameObject(floor);
}
GameScene::~GameScene()
{
delete player;
}
void GameScene::start()
{
Scene::start();
// Initialize any scene logic here
}
void GameScene::draw()
{
Scene::draw();
}
void GameScene::update()
{
Scene::update();
if (player->getOnFloor() == false) {
player->setY -= 1;
}
else {
player->setY = 0;
}
}
This code is from my Player.h where the setters and getters are located
#pragma once
#include "GameObject.h"
#include "common.h"
#include "draw.h"
class Player :
public GameObject
{
public:
void start();
void update();
void draw();
//X Setter
void setX(int x) {
x = x;
}
//X Getter
int getX() {
return x;
}
//Y Setter
void setY(int y) {
y = y;
}
//Y Getter
int getY() {
return y;
}
//Height Setter
void setHeight(int height) {
height = height;
}
//Height Getter
int getHeight() {
return height;
}
//Width Setter
void setWidth(int width) {
width = width;
}
//Width Getter
int getWidth() {
return width;
}
//OnFloor Setter
void setOnFloor(int onFloor) {
onFloor = onFloor;
}
//OnFloor Getter
int getOnFloor() {
return onFloor;
}
private:
SDL_Texture* texture;
int x;
int y;
int height;
int width;
int speed;
bool onFloor;
};
I have tried putting () beside the setY like this
if (player->getOnFloor() == false) {
player->setY() -= 1;
}
else {
player->setY)( = 0;
}
But it still did not work, I was expecting it to make my player fall down but VS studio kept showing me the error
this may be a noobie question but I am still a noobie programmer so please bear with me
EDITED:
The player is now falling upwards, I tried doing -= 1 to make him fall downwards
void GameScene::update()
{
Scene::update();
if (player->getOnFloor() == false) {
player->setY(player->getY() -= 1);
}
else {
player->setY(0);
}
}
but I get an error on player in "player->getY()" saying that expression must be a modifiable lvalue
The error you are getting is because you are trying to use the setY setter function as a variable. In order to use the setter function to set the y property of the player object, you need to call the setY function and pass in the new value for y as an argument. Here is how you would use the setY setter function in your GameScene::update function:
void GameScene::update()
{
Scene::update();
if (player->getOnFloor() == false) {
player->setY(player->getY() + 1);
}
else {
player->setY(0);
}
}
Note that in this example, we are calling the getY getter function to get the current value of y, and then subtracting 1 from it before passing the result to the setY setter function. This will update the y property of the player object and make it fall down by 1 unit each time the update function is called.
I am making a collision detection system for a text based game using co-ordinates. I am trying to retrieve the x and y positions of my player and an array of monsters. The co-ordinates are held in a bass class Character. when i try to retrieve the data it returns Xpos -858993460 which i am assuming is comming from the pointers i am using.
#include <iostream>
#include <ctime>
#include <cstdlib>
using namespace std;
const int MON_SIZE = 10;
monster* monArr[MON_SIZE];
player player1;
bool collision();
int main(){
void initialise();
player1.moveChar(3, 6);
bool temp;
temp = collision();
if (temp = true){
cout << endl << "collision detected" << endl;
}
system("pause");
return 0;
}
void initialise()
{
srand(time(NULL));
for (int i = 0; i < 10; i++)
{
int inx = rand() % 9;
int iny = rand() % 9;
monArr[i] = new monster();
monArr[i]->moveChar(inx, iny);
}
}
bool collision()
{
bool collision;
for (int i = 0; i < 10; i++)
{
int mx, my, px, py;
monArr[i]->getPos(mx, my);
player1.getPos(px, py);
if (mx == px && my == py)
{
collision = true;
cout << endl << mx << " " << my << endl;
}else collision = false;
}
return collision;
}
#pragma once
#include "character.h"
class player :
public character
{
private:
public:
player();
~player();
};
#pragma once
#include "character.h"
class monster :
public character
{
public:
monster();
~monster();
private:
};
#include "character.h"
#include <iostream>
using namespace std;
character::character()
{
xpos = 0;
ypos = 0;
}
character::~character()
{
}
void character::moveChar(int Xpos, int Ypos)
{
xpos = Xpos;
ypos = Ypos;
}
void character::printPos(){
cout << "Position: " << xpos << " . " << ypos << endl;
}
void character::getPos(int& Xpos, int& Ypos){
Xpos= xpos;
Ypos= ypos;
}
#pragma once
class character
{
public:
character();
~character();
void moveChar(int Xpos, int Ypos);
void printPos();
void getPos(int& Xpos, int& Ypos);
protected:
int xpos;
int ypos;
};
int main(){
void initialise();
...
The above does not call the function initialize. Although you did not post that function, I suppose it initializes your arrays and variables... Write instead:
int main(){
initialise();
...
And move the definition of initialize() to before main, or at least put a declaration of its prototype.
Change your charactoer::getPos function to this:
void character::getPos(int& Xpos, int& Ypos){
Xpos = xpos;
Ypos = ypos;
}
The statement Xpos *= xpos is equivalent to Xpos = Xpos * xpos. This is not what you want, especially since your Xpos argument is not initialize.
I'm trying to construct a two-dimensional boolean array with a class I've created called Grid. The Grid object is a private member class of another class called GameOfLife. Whenever I create a GameOfLife object with the parameters belove, the Grid object first gets created with the default constructor, then it gets created again with the constructor with parameters, and then for some reason Grid's deconstructor runs and deletes everything ? I'm really out of ideas :p I'm running MinGW GCC on Eclipse Luna.
Main.cpp
const int HEIGHT = 25;
const int WIDTH = 25;
#include <iostream>
#include "GameOfLife.h"
int main(int argc, const char * argv[]) {
GameOfLife game = GameOfLife(HEIGHT, WIDTH, false);
game.play();
return 0;
}
Grid.h
#ifndef __Game_Of_Life__Grid__
#define __Game_Of_Life__Grid__
#include <stdio.h>
class Grid {
public:
Grid(int y, int x, bool state);
Grid();
void allocate(int x, int y, bool state);
void deallocate();
void set(int x, int y, bool state);
bool get(int x, int y);
void setAll(bool state);
void switchBoards();
~Grid();
private:
bool ** oldGeneration;
bool ** newGeneration;
int height;
int width;
};
#endif /* defined(__Game_Of_Life__Grid__) */
Grid.cpp
#include "Grid.h"
Grid::Grid(int y, int x, bool state) {
allocate(x, y, state);
}
void Grid::allocate(int x, int y, bool state) {
height = y;
width = x;
oldGeneration = new bool*[height];
newGeneration = new bool*[height];
for (int i = 0; i < height; i++) {
oldGeneration[i] = new bool[width];
newGeneration[i] = new bool[width];
}
}
Grid::~Grid() {
deallocate();
}
void Grid::switchBoards() {
bool ** temp = oldGeneration;
oldGeneration = newGeneration;
newGeneration = temp;
delete temp;
}
bool Grid::get(int x, int y) {
return oldGeneration[y][x];
}
void Grid::set(int x, int y, bool state) {
newGeneration[y][x] = state;
}
void Grid::deallocate() {
if (oldGeneration != NULL || newGeneration != NULL) {
for (int i = 0; i < height; i++) {
delete [] oldGeneration[i];
delete [] newGeneration[i];
}
delete [] oldGeneration;
delete [] newGeneration;
}
return;
}
Grid::Grid() {
oldGeneration = NULL;
newGeneration = NULL;
width = 0;
height = 0;
}
void Grid::setAll(bool state) {
for (int i = 0; i < height; i++) {
for (int n = 0; n < width; n++) {
newGeneration[i][n] = state;
}
}
}
GameOfLife.h
#ifndef __Game_Of_Life__GameOfLife__
#define __Game_Of_Life__GameOfLife__
#include <stdio.h>
#include "Grid.h"
#include <iostream>
class GameOfLife {
private:
Grid board;
public:
GameOfLife(int y, int x, bool state);
GameOfLife();
~GameOfLife();
void play();
void welcome();
void makeBoard();
void updateBoard();
int findAliveNeighbours(int x, int y);
};
#endif /* defined(__Conway__GameOfLife__) */
GameOfLife.cpp
#include "GameOfLife.h"
const int WIDTH = 100;
const int HEIGHT= 75;
GameOfLife::GameOfLife(int y, int x, bool state) {
board = Grid(y, x, state);
}
GameOfLife::GameOfLife() {
board = Grid();
}
GameOfLife::~GameOfLife() {
board.deallocate();
}
void GameOfLife::play() {
welcome();
makeBoard();
for (int i = 0; i < HEIGHT; i++) {
for (int n = 0; n < WIDTH; n++) {
std::cout << board.get(n,i) << " ";
}
std::cout << std::endl;
}
updateBoard();
std::cout << std::endl;
for (int i = 0; i < HEIGHT; i++) {
for (int n = 0; n < WIDTH; n++) {
std::cout << board.get(n,i) << " ";
}
std::cout << std::endl;
}
}
void GameOfLife::makeBoard() {
int x1,x2,x3,x4, y1,y2,y3,y4;
x1 = 10; y1 = 10;
x2 = 10; y2 = 11;
x3 = 10; y3 = 12;
x4 = 11; y4 = 13;
int x5 = 0; int y5 = 0;
board.set(x1, y1, true);
board.set(x2, y2, true);
board.set(x3, y3, true);
board.set(x4, y4, true);
board.set(x5, y5, true);
}
void GameOfLife::welcome() {
std::cout << "Welcome to Conway's Game Of Life"
<< std::endl;
}
GameOfLife::GameOfLife(int y, int x, bool state) {
// board is a member variable that gets initialized
// with the default constructor.
// Then it gets replaced by assignment with a different
// Grid object. The temporary object gets deleted at
// the end of the line.
board = Grid(y, x, state);
}
Change the implementation to:
GameOfLife::GameOfLife(int y, int x, bool state) : board(y, x, state) {}
Similarly, change the default constructor to:
GameOfLife::GameOfLife() {}
The more important problem that needs to be fixed is that you are breaking The Rule of Three.
You need to add proper implementations of the copy constructor and the copy assignment opertor in Grid.
The other, and better, option is to change the internal data of Grid to
std::vector<std::vector<bool>> oldGeneration;
std::vector<std::vector<bool>> newGeneration;
Then, the compiler generated copy constructor and copy assignment operator will be good enough.
I cannot modify the member values of a class object because of the above error:
When I call my initialize function to initialize my "garo" object, I receive the following run-time error,
"Unhandled exception at 0x01323976 in Heretic.exe: 0xC0000005: Access violation reading location 0x00000008."
NOTE: The class Garo is a child of Object.
THE CODE
Garo.h
#pragma once
#include "Object.h"
class Garo : public Object
{
private:
int animationRow;
public:
Garo();
void Destroy();
void Init(ALLEGRO_BITMAP *image = NULL);
void Update();
void Render();
void MoveLeft();
void MoveRight();
void Idle();
void SetAnimationRow(int row);
};
Garo.cpp
#include "Garo.h"
Garo::Garo()
{
Object::Init(20, 200, 3, 0, 0, 0, 16, 24);
}
void Garo::Init(ALLEGRO_BITMAP *image)
{
Object::Init(20, 200, 3, 0, 0, 0, 16, 24);
SetID(PLAYER);
SetAlive(true);
maxFrame = 3;
curFrame = 0;
frameWidth = 32;
frameHeight = 48;
animationColumns = 4;
animationDirection = 1;
animationRow = 0;
if(image != NULL)
Garo::image = image;
}
... the rest has been abbreviated
Object.h
#pragma once
#include <iostream>
#include <allegro5/allegro5.h>
#include <allegro5/allegro_primitives.h>
#include "Globals.h"
class Object
{
private:
int ID;
bool alive;
bool collidable;
protected:
float x;
float y;
float velX;
float velY;
int dirX;
int dirY;
int boundX;
int boundY;
int maxFrame;
int curFrame;
int frameCount;
int frameDelay;
int frameWidth;
int frameHeight;
int animationColumns;
int animationDirection;
ALLEGRO_BITMAP *image;
public:
Object();
void virtual Destroy();
void Init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY);
void virtual Update();
void virtual Render();
float GetX() {return x;}
float GetY() {return y;}
void SetX(float x) {Object::x = x;}
void SetY(float y) {Object::y = y;}
int GetBoundX() {return boundX;}
int GetBoundY() {return boundY;}
int GetID() {return ID;}
void SetID(int ID) {Object::ID = ID;}
bool GetAlive() {return alive;}
void SetAlive(bool alive) {Object::alive = alive;}
bool GetCollidable() {return collidable;}
void SetCollidable(bool collidable) {Object::collidable = collidable;}
bool CheckCollisions(Object *otherObject);
void virtual Collided(int objectID);
bool Collidable();
};
Object.cpp
#include "Object.h"
Object::Object()
{
x = 0;
y = 0;
velX = 0;
velY = 0;
dirX = 0;
dirY = 0;
boundX = 0;
boundY = 0;
maxFrame = 0;
curFrame = 0;
frameCount = 0;
frameDelay = 0;
frameWidth = 0;
frameHeight = 0;
animationColumns = 0;
animationDirection = 0;
image = NULL;
alive = true;
collidable = true;
}
void Object::Init(float x, float y, float velX, float velY, int dirX, int dirY, int boundX, int boundY)
{
std::cout << "HERE?" << std::endl;
Object::x = x;
Object::y = y;
Object::velX = velX;
Object::velY = velY;
Object::dirX = dirX;
Object::dirY = dirY;
Object::boundX = boundX;
Object::boundY = boundY;
}
The Calling Code
Garo *garo;
// ...
garo->Init(garo_img);
This is where I receive the run-time error. I'm using Allegro libraries, so feel free to ask about any weird types you may see. I am stilling learning C++, so please help me to understand in rudimentary terms.
You need to instantiate an object instance to operate on. For example:
garo = new Garo();
By missing this out you are trying to invoke methods on an uninitialized variable. You should probably consider using some form of smart pointer to ensure that the object is destroyed.
I have made a class and it compiles with no syntax errors, but I get 6 unresolved external symbols?
THE CLASS:
struct CELL {
private:
static bool haslife;
static int x;
static int y;
public:
static bool has_life()
{
return haslife;
}
static void set_coords(int xcoord, int ycoord)
{
x = xcoord;
y = ycoord;
}
static void get_coords(int &xcoord, int &ycoord)
{
xcoord = x;
ycoord = y;
}
};
class cell_grid {
private:
static int cell_size;
static int cell_count_x;
static int cell_count_y;
CELL **cell;
public:
cell_grid();
cell_grid(unsigned int width,unsigned int height, unsigned int cellsize)
{
//set size based on cellsize
this->cell_size = cellsize;
this->cell_count_x = floor((double)width / this->cell_size);
this->cell_count_y = floor((double)height / this->cell_size);
this->cell = new CELL*[this->cell_count_y];
for(int i = 0; i < this->cell_count_y; i++)
{
cell[i] = new CELL[this->cell_count_x];
}
for(int y = 0; y < this->cell_count_y; ++y)
{
for(int x = 0; x < this->cell_count_x; ++x)
{
int cur_x = x * this->cell_size;
int cur_y = y * this->cell_size;
this->cell[x][y].set_coords(cur_x,cur_y);
}
}
} //end of constructor
static int get_cell_size()
{
return cell_size;
}
static void render(BITMAP *buff)
{
circlefill(buff,70,70,60,makecol(27,37,0));
}
};
MAIN
int main()
{
start_allegro();
cell_grid *grid = new cell_grid(scr_w,scr_h,10);
grid->render(buffer);
//Main Loop
while (!done && !key[KEY_ESC]) //until 'X' pressed or ESC
{
//***** Start Main Code Here *****
while (speed_counter > 0)
{
//render the buffer to the screen
blit(
buffer,
screen,
0,0,0,0,
scr_w,
scr_h);
clear_bitmap(buffer);
speed_counter --;
}
//***** End Main Code Here *****
rest(1); //Normalize cpu usage
}
return 0;
}
END_OF_MAIN()
Thanks
Don't define all of the class variables as static.
When you define a data member as static it means there is only one single instance of it. This doesn't seem to be what you want to do here.
Instead of
private:
static bool haslife;
static int x;
static int y;
write:
private:
bool haslife;
int x;
int y;
Further more, when you define a static member, you need to define it again in the CPP file and initialize it with a value. It doesn't look like you're doing that and that's why you're getting the linker errors.
Also, next time you post something, make sure you actually ask a question rather than just simply stating facts.