Im trying to figure out how to use pointers to make a single instance of an object that in this example will just change direction on x-axis.
Splav.h (eng. Paddle.h)
#pragma once
#include "SDL.h"
#include "Prikazi.h"
class Prikazi;
class Splav
{
private:
int splavTrenutniX = 0, splavTrenutniY = 0; //current x and y axis position of the paddle
int splavPocetniX, splavPocetniY; //starting position of paddle
public:
Prikazi *pr; //pointer to the Prikazi (eng. Draw) class
SDL_Rect rectSplav; //Rect used to store texture of paddle
Splav(); //default constructor, used to initialize paddle for 1st load or reset
Splav(int trenutniX, int trenutniY); //overload constructor where current x and y points on axis become points on paddle movement
void gibanjeSplavi(); //move the paddle
};
Splav.cpp (eng. Paddle.cpp)
#include "Splav.h"
Splav::Splav()
{
splavPocetniX =pr->sirinaEkrana / 2; //sirinaEkrana = Screen width
splavPocetniY = pr->visinaEkrana - pr->visinaSplavi; // screen height- paddle height
rectSplav.x = splavPocetniX;
rectSplav.y = splavPocetniY;
rectSplav.w = pr->sirinaSplavi;
rectSplav.h = pr->visinaSplavi;
}
Splav::Splav(int trenutniX, int trenutniY)
{
splavTrenutniX = trenutniX;
splavTrenutniY = trenutniY;
gibanjeSplavi();
}
void Splav::gibanjeSplavi() //when paddle starts to move
{
const Uint8 *tipka = SDL_GetKeyboardState(NULL);
if (tipka[SDL_SCANCODE_A] && rectSplav.x > 0)
rectSplav.x--;
if (tipka[SDL_SCANCODE_D] && rectSplav.x < 1280-pr->sirinaSplavi) //1280-200(paddle width)
rectSplav.x++;
}
Prikazi.h (eng. Draw.h)
#pragma once
#include "SDL_image.h"
#include "Splav.h"
class Splav;
class Prikazi
{
private:
SDL_Window * ekran = NULL;
SDL_Renderer *renderer;
SDL_Texture *pozadina;
SDL_Texture *splav;
SDL_Texture *loptica;
SDL_Rect rectPozadina;
public:
Splav *sp ;
const int sirinaEkrana = 1280, visinaEkrana = 720; //screen width and height
const int sirinaSplavi = 200, visinaSplavi = 10; //paddle width and height
Prikazi();
~Prikazi();
void crtajPocetno();
SDL_Rect initRect(int x, int y, int sirina, int visina);
};
Prikazi.cpp (eng. Draw.cpp)
#include "Prikazi.h"
Prikazi::Prikazi()
{
ekran = SDL_CreateWindow("Breakout", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, sirinaEkrana, visinaEkrana, SDL_WINDOW_SHOWN);
renderer = SDL_CreateRenderer(ekran, -1, 0);
pozadina= IMG_LoadTexture(renderer, "Assets/pozadina1.png");
loptica = IMG_LoadTexture(renderer, "Assets/loptica.bmp");
splav = IMG_LoadTexture(renderer, "Assets/splav.bmp");
rectPozadina = initRect(0, 0, sirinaEkrana, visinaEkrana);
//this is where I get nullptr value
sp->rectSplav = initRect(sp->rectSplav.x, sp->rectSplav.y, sirinaSplavi, visinaSplavi);
crtajPocetno();
}
Prikazi::~Prikazi()
{
//SDL_DestroyWindow(ekran);
}
void Prikazi::crtajPocetno()
{
SDL_RenderClear(renderer);
SDL_RenderCopy(renderer, pozadina, NULL, &rectPozadina);
SDL_RenderCopy(renderer, splav, NULL, &(sp->rectSplav));
SDL_SetRenderTarget(renderer, pozadina);
SDL_SetRenderTarget(renderer, splav);
SDL_SetRenderTarget(renderer, NULL);
SDL_RenderPresent(renderer);
}
SDL_Rect Prikazi::initRect(int x, int y, int sirina, int visina)
{
SDL_Rect r;
r.x = x;
r.y = y;
r.w = sirina;
r.h = visina;
return r;
}
My question is: How to define that pointer so I can just use it to store Rect coordinates to my Prikazi class (eng. Draw) so It can use that info to render it on the screen? Same question goes to creating Prikazi pointer inside Splav.h ( so I can use constants for screen height, width etc. )
1 Answer 1
As far as I can see you never initialise your pointer.
You declare Splav *sp
but never create a new Splav
instance which means trying to call a method later is undefined behaviour. So you would need to pass in a Splav pointer into the constructor, or construct a new pointer inside it, however....
The bigger problem is that in Splav
you have a pointer to Prikazi
and in Prikazi
you have a pointer to Splav
. This is a circular dependency - you need a Splav to create a Prikazi
but you need a Prikazi
to create a Splav
. This is a bad situation to be in, essentially having a chicken & egg situation.
#include "Prikazi.h"
class Prikazi;
You don't need to forward-declare if you are already including the header. Forward-declaring is essentially promising the compiler that there will be a class when it needs it, but not right now.
You need to ask yourself if these two classes really need to know about each other before coupling them so closely. For example in Splav
all you really seem to do is take the width and height from Prikazi
and store them internally - that in itself is a bit questionable but if you need to do it then just pass in two integers in the constructor. Then you need to instantiate a Splav
item and pass it into Prikazi
and store it in the sp
variable.
Overall, your problem is stemming from poor design and I would really recommend picking up a book (or watch a tutorial) on the very basics of c++ programming. A tip for the future is to write all your code in English, makes it much easier to follow along which helps when you need to ask questions. Also upon reaching this point I realise we're in the gamedev section and this isn't really related to game programming but really the basics of programming - but I already typed it out so there we go.