Calling a method in a method of another class

Hey guys :D

Situation:
I have created a "CSprite"-class in a separate header-file. It contains two functions called "Load (Param, Param, Param, Param)" and "Render ()". Those two functions seem to be declared and defined just fine.

1
2
3
4
//CSprite.h
    public:
        void Load(const char* cPath, int R, int G, int B);
        void Render ();


Now I have a “CPlayer”-class in another separate header-file. In the “CPlayer”-class there are two functions called “Init ()” and “Render ()”. In my “CPlayer.cpp”-file I want to call the “Sprite.Load(…,…,…,…)” – function in my “CPlayer::Init()”-function and call the “Sprite.Render()” – function in my “CPlayer::Render()”-function.

1
2
3
4
5
6
7
8
9
10
11
12
//CPlayer.cpp
//CSprite SpritePlayer;     <--defined in CPlayer.h

void CPlayer::Init()
{
    SpritePlayer.Load("data/imgs/player/Ash_Sprite.bmp", 255, 0, 255);
}

void CPlayer::Render()
{
    SpritePlayer.Render();
}

I hope it’s comprehensible so far… Then I want to call my “Player.Render()”-function in another function called “CGame::OnRender()”.


1
2
3
4
5
6
7
8
9
10
11
//CGame.cpp
//CPlayer PlayerSprite;     <--defined in CGame.h

void CGame::OnRender()
{
    SDL_SetRenderDrawColor(MainRenderer,0,0,255,255);

    PlayerSprite.Render() // <--does not work

    SDL_RenderPresent(MainRenderer);
}

The same is with the “Player.Init()”-function. I would like to call that function in “CGame::OnInit()”.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
//CGame.cpp
//CPlayer PlayerSprite;     <--defined in CGame.h
bool CGame::OnInit()
{

    if (SDL_Init (SDL_INIT_EVERYTHING) < 0)
    {
        …
    }
    …

    PlayerSprite.Load("data/imgs/player/Ash_Sprite.bmp", 255, 0, 255) // <--does not work

    return true;
}



Problem:
As soon as I run my little program I see a white window and soon after that a little window pops up saying “app.exe doesn’t work anymore” “Due to a problem the program was not executed correctly. The program will be closed and you will be contacted as soon as a solution is available”


Code:
I could upload the code itself on thursday evening if you Need it?

Thanks a lot and cheers

HalfNOoB
Last edited on
closed account (10X9216C)
Use a debugger with the program compiled in debug to get some more meaningful information.
I dont quite get what you want me to do... I'm still new with the environement and how to use it. Could you please explain that to me? Sounds like a useful Point to start off :)

If it does help: I'm using Code::Blocks 12.11
When you run from the debugger... and get the program to crash... the debugger should snap and take you to the exact line of code where the crash is happening.

In C::B, run your program by selecting "Start / Continue" from the 'Debug' menu. Get it to crash. It should give you more meaningful information about the crash.
@Disch: Thanks alot :D I did as you say and this is the result I got:

#0 00401644 CGame::GetRenderer(this=0x0) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CGame.cpp:115)
#1 00401958 CSprite::Load(this=0x47703c, cPath=0x46e0f4 <_ZSt16__convert_from_vRKPiPciPKcz+4645108> "data/imgs/player/Ash_Sprite.bmp", R=255, G=0, B=255) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CSprite.cpp:22)
#2 0040183C CPlayer::Init(this=0x47703c) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CPlayer.cpp:13)
#3 0040152A CGame::OnInit(this=0x477020) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CGame.cpp:58)
#4 004016F3 SDL_main(argc=argc@entry=1, argv=argv@entry=0x330008) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CMain.cpp:8)
#5 0040232C console_main(argc=argc@entry=1, argv=argv@entry=0x330008) (../src/main/windows/SDL_windows_main.c:140)
#6 004024ED WinMain@16(hInst=0x400000, hPrev=0x0, szCmdLine=0x813e29 "", sw=10) (../src/main/windows/SDL_windows_main.c:177)
#7 0046B48B main () (??:??)

As far as I was doing debugging I have learnt to always fix the first error you get. Sometimes the other errors disappear along with the first one.



The first error here refers to the following function:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//CGame.h : I cut out the includes and the #ifndefs and #endifs

class CGame
{
    public:
        CGame();

        bool OnInit();
        void OnEvent(SDL_Event* Event);
        void OnLoop(); //Data Updates
        void OnRender();
        void OnCleanup();

        int GetScreenWidth();
        int GetScreenHeight();

        SDL_Renderer* GetRenderer();                                   //<--This is the first error

        bool bRunning;                                 //Yeah I know should be private

    private:
        int SCREEN_WIDTH;
        int SCREEN_HEIGHT;

        SDL_Window* MainWindow;
        SDL_Renderer* MainRenderer;                                         //Here is the Renderer
        SDL_Surface* MainWindowSurface;

        CPlayer Player;

};


1
2
3
4
5
6
//CGame.cpp: Here as well: everything cut down to this function

SDL_Renderer* CGame::GetRenderer()
{
    return MainRenderer;
}



I guess that the primary error lies there… Because the next error refers to my “CSprite::Load()”-function, which makes use of the “CGame::GetRenderer()”-function. The next error is in my “CPlayer::Init()”-function where my “CSprite::Load()”-function is being called. The next error is in my “CGame::OnInit()”-function where my “CPlayer::Init()”-function is being called. The next error is in the “main”-function where my “CGame::OnInit()”-function is being called.

So basically my first error produces another error, which leads to another error …

I hope I got that right. I’m not sure whether it’s a problem with the pointers or with not using SDL correctly. (the second would have nothing to do with this forum)

Would be create if you could help me and explain me what I did wrong…

Thanks for all of your answers so far

Cheers HalfNOoB
#0 00401644 CGame::GetRenderer(this=0x0)


That's your problem. The 'this' pointer is null.

This means you are attempting to dereference a null CGame pointer. IE you're doing this:

 
mygame->GetRenderer();


where 'mygame' is a null pointer.

So... look at the code that is calling this (CSprite::Load) and make sure your game pointer is non-null.
Yeah you are absolutely right: Im doing something like "mygame->GetRenderer()"

But still: I don't know any other way to do that...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
//CSprite.h

#ifndef _CSPRITE_H_
    #define _CSPRITE_H_

#include "SDL.h"
#include "SDL_image.h"


class CGame; //<-- Forward declaration


class CSprite
{
    public:
        CSprite();

    public:
        void Load(const char* cPath, int R, int G, int B);
        void Render ();

    private:
        SDL_Rect rcDest;
        SDL_Surface* sImage;
        SDL_Texture* tImage;

        CGame* Game;                //<-- Needs to be pointer because of Forward declaration

};



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
 //CSprite.cpp

#include "CSprite.h"
#include "CGame.h"
#include <iostream>

CSprite::CSprite()
{
    sImage = NULL;
    tImage = NULL;
}


void CSprite::Load (const char* cPath, int R, int G, int B)
{
    sImage = IMG_Load(cPath);
    if (sImage == NULL)
    {
        std::cout << "Fehler beim Laden von " << cPath << "! SDL_Error: " << SDL_GetError() << "\n";
    }
    else
    {
        SDL_SetColorKey(sImage, SDL_TRUE, SDL_MapRGB(sImage-> format, R, G, B));
        tImage = SDL_CreateTextureFromSurface(Game->GetRenderer(), sImage);                       //<-- Thats what you mean 
        if (tImage == NULL)
        {
            std::cout << "Fehler beim Umwandeln von einer Surface in eine Textur der Grafik " << cPath << "! SDL_Error: " << SDL_GetError() <<"\n";
        }
        SDL_FreeSurface (sImage);
    }
}


void CSprite::Render()
{
    SDL_RenderCopy (Game->GetRenderer(),tImage,NULL,&rcDest);
}


Any idea how I can fix that? (Sorry for making you do all the thinking :( )
#0 00401644 CGame::GetRenderer(this=0x0) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CGame.cpp:115)
#1 00401958 CSprite::Load(this=0x47703c, cPath=0x46e0f4 <_ZSt16__convert_from_vRKPiPciPKcz+4645108> "data/imgs/player/Ash_Sprite.bmp", R=255, G=0, B=255) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CSprite.cpp:22)
#2 0040183C CPlayer::Init(this=0x47703c) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CPlayer.cpp:13)
#3 0040152A CGame::OnInit(this=0x477020) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CGame.cpp:58)
#4 004016F3 SDL_main(argc=argc@entry=1, argv=argv@entry=0x330008) (C:\Users\Lino\Documents\1 Data Lino\Freizeit\1 Programmieren\C++ & SDL2\C++\RunningMan\CMain.cpp:8)
#5 0040232C console_main(argc=argc@entry=1, argv=argv@entry=0x330008) (../src/main/windows/SDL_windows_main.c:140)
#6 004024ED WinMain@16(hInst=0x400000, hPrev=0x0, szCmdLine=0x813e29 "", sw=10) (../src/main/windows/SDL_windows_main.c:177)
#7 0046B48B main () (??:??)


BTW, those are not errors. What you're seeing is your call stack. Starting at the bottom, main (#7) called WinMain (#6). WinMain called console_main (#5), etc. until CSprite::Load (#1) was called. CSprite::Load in turn called CGame::GetRenderer. You can see the arguments to each function in parenthises.
But still: I don't know any other way to do that...


There's nothing wrong with that.

The problem is that you never set your 'Game' pointer to point to anything. It has to point to a Game object for it to work. Right now it points to null/nothing. Which is why your program is crashing.


I'm assuming you have created a CGame object somewhere else in your program, right? You need to make every CSprite's 'Game' pointer point to that object.
Yeah I created another object of "CGame". It's in my "Main.cpp"-file where the entry point of the game is defined...

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
 //CMain.cpp

#include "CGame.h"

CGame Game;                                        //<-- Here


int main (int argc, char* argv [])
{
    if(Game.OnInit() == false)
    {
        return -1;
    }

    SDL_Event Event;

    while(Game.bRunning)
    {
        while(SDL_PollEvent(&Event))
        {
            Game.OnEvent(&Event);
        }

        Game.OnLoop(); //Update
        Game.OnRender();
    }

    Game.OnCleanup();


    return 0;
} 



I'm the absolute worst when it comes to pointers ^^' I don't get of what use they are... If you have the variable name / the adress of the variable why should i manipulate it not directly but save it in a pointer first??? Well thats out of topic here anyway.
So where do I make all my pointers in "CSprite" point to the Object created in "CMain.cpp"? (Yeah I'm deeply ashamed that after this much help I'm still way too dumb...)
Can you show us CSprite::Load ? Because the problem is in there.

As Disch pointed out in a previous post, you're doing something like the following:
 
  mygame->GetRenderer();  //  mygame pointer is null rather than pointing to Game in main. 
Yeah for sure :D (Though I have posted it above already)


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
//CSprite.h
#ifndef _CSPRITE_H_
    #define _CSPRITE_H_

#include "SDL.h"
#include "SDL_image.h"


class CGame;


class CSprite
{
    public:
        CSprite();

    public:
        void Load(const char* cPath, int R, int G, int B);                  //<--Here
        void Render ();

    private:
        SDL_Rect rcDest;
        SDL_Surface* sImage;
        SDL_Texture* tImage;

        CGame* Game;

};



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
//CSprite.cpp
#include "CSprite.h"
#include "CGame.h"
#include <iostream>

CSprite::CSprite()
{
    sImage = NULL;
    tImage = NULL;
}


void CSprite::Load (const char* cPath, int R, int G, int B)
{
    sImage = IMG_Load(cPath);
    if (sImage == NULL)
    {
        std::cout << "Fehler beim Laden von " << cPath << "! SDL_Error: " << SDL_GetError() << "\n";
    }
    else
    {
        SDL_SetColorKey(sImage, SDL_TRUE, SDL_MapRGB(sImage-> format, R, G, B));
        tImage = SDL_CreateTextureFromSurface(Game->GetRenderer(), sImage);                       //<-- Thats what you mean
        if (tImage == NULL)
        {
            std::cout << "Fehler beim Umwandeln von einer Surface in eine Textur der Grafik " << cPath << "! SDL_Error: " << SDL_GetError() <<"\n";
        }
        SDL_FreeSurface (sImage);
    }
}


void CSprite::Render()
{
    SDL_RenderCopy (Game->GetRenderer(),tImage,NULL,&rcDest);
}


Thanks :)
std::string is a class which contains a string. You can have as many std::string objects in your program as you want... and each of those strings will operate independently of all other strings.

Similarly... CGame is a class. You can have as many CGame objects in your program as you want... and each of those CGames will (or should) operate independently of all other CGames.


So conceptually.. you could have more than 1 CGame object... even though you only have 1.

C++ does not know you only have 1. Nor does it care. You always have to tell it which CGame object you want to use. Since you only have the one... you will be telling it to use the same CGame object every time.


The problem is... you are not doing that. In main, you have your 'Game' object... but that object is not visible inside your CSprite class. Each CSprite class has it's own pointer (read: not object). Logically... since you only want 1 CGame object... you would want your pointers to point to main's Game object.

But... you never make those pointers point to anything. So they're just pointing to random garbage address and assuming that there's a game object at that address. Since there isn't -- your program is crashing.

You have to explicitly set these pointers to point to a valid object. That is the only way to fix this problem.

This could be done in Sprite's ctor, by passing the Game object to the sprite, allowing it to initialize its pointer:

1
2
3
4
5
6
CSprite::CSprite(CGame* thegame)
{
    Game = thegame;  // make your pointer point to whatever CGame object was supplied
    sImage = NULL;
    tImage = NULL;
}


Then, of course... when you construct your CSprite, you will need to give it a CGame object. I don't see where you're constructing your CSprite object so I can't show how to do it... but hopefully you get the idea.



That's really all there is to it. If your CSprites are accessing the CGame object... you need to actually give them the CGame object. They don't just automatically have it.
Though I have posted it above already.

Sorry. Didn't scroll back far enough.

csprite.cpp line 23:
 
tImage = SDL_CreateTextureFromSurface(Game->GetRenderer(), sImage);                       //<-- Thats what you mean  

Yes, that's exactly what we mean. The Game pointer in your CSprite object was never initialized. So as Disch said, you're trying to dereference a null pointer. Crash. Bang.



Wow Thank you for that long explanation O_o :O I think I got what the two of you meant. Unfortunately I already turned down my computer so I will have to test it out tomorrow evening :(

If I'm still too dumb I will just ask here again :D

Good night :)
I now understand why the program crashes but I don’t understand how to fix it… Where should the pointer of the type „CGame“ point to???

Here is my actual code: Where should it be altered? and into what? :/

The problem I have is about pointers right? Guess I will go over that and find a few tutorials to finally understand them :(


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
//CMain.cpp

#include "CGame.h"

CGame Game;


int main (int argc, char* argv [])
{
    if(Game.OnInit() == false)
    {
        return -1;
    }

    SDL_Event Event;

    while(Game.bRunning)
    {
        while(SDL_PollEvent(&Event))
        {
            Game.OnEvent(&Event);
        }

        Game.OnLoop(); //Update
        Game.OnRender();
    }

    Game.OnCleanup();


    return 0;
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
//CGame.h


#ifndef _CGAME_H_
    #define _CGAME_H_


#include "SDL.h"
#include "SDL_image.h"
#include "CSprite.h"
#include "CPlayer.h"
#include "CInput.h"

class CInput;

class CGame
{
    public:
        CGame();


    public:

        bool OnInit();
        void OnEvent(SDL_Event* Event);
        void OnLoop(); //Data Updates
        void OnRender();
        void OnCleanup();

        int GetScreenWidth();
        int GetScreenHeight();

        SDL_Renderer* GetRenderer();
        //SDL_Event* GetEvent();

        bool bRunning;

    private:
        int SCREEN_WIDTH;
        int SCREEN_HEIGHT;

        SDL_Window* MainWindow;
        SDL_Renderer* MainRenderer;
        //SDL_Event MainEvent;
        SDL_Surface* MainWindowSurface;

        CPlayer Player;
        CInput* Input;

};


#endif // _CGAME_H_ 


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
//CGame.cpp

#include "CGame.h"


#include <iostream>

CGame::CGame()
{
    bRunning = true;

    SCREEN_WIDTH = 640;
    SCREEN_HEIGHT = 480;

    MainWindow = NULL;
    MainRenderer = NULL;
    MainWindowSurface = NULL;

}



bool CGame::OnInit()
{

    if (SDL_Init (SDL_INIT_EVERYTHING) < 0)
    {
        std::cout << "SDL could not be initialized! SDL_Error: " << SDL_GetError ();
    }
    else
    {
        MainWindow = SDL_CreateWindow ("The Running Man",SDL_WINDOWPOS_CENTERED,SDL_WINDOWPOS_CENTERED,SCREEN_WIDTH,SCREEN_HEIGHT,SDL_WINDOW_SHOWN);
        if (MainWindow == NULL)
        {
            std::cout << "SDL could not create the window! SDL_Error: " << SDL_GetError () << "\n";
        }
        else
        {
            MainRenderer = SDL_CreateRenderer(MainWindow, -1, SDL_RENDERER_ACCELERATED);
            if (MainRenderer == NULL)
            {
                std::cout << "SDL could not create the renderer! SDL_Error: " << SDL_GetError() << "\n";
            }
            else
            {
                MainWindowSurface = SDL_GetWindowSurface(MainWindow);
                if (MainWindowSurface == NULL)
                {
                    std::cout << "SDL could not get the window surface! SDL_Error: " << SDL_GetError() << "\n";
                }
            }
        }
    }

    Player.Init();             //I wanna do it like this :(

    return true;
}


void CGame::OnEvent(SDL_Event* Event)
{

    //Input->HandleAllInput();

    if(Event->type == SDL_QUIT)
    {
        bRunning = false;
    }
}


void CGame::OnLoop()
{

}

void CGame::OnRender()
{

    SDL_SetRenderDrawColor(MainRenderer,0,0,255,255);

    SDL_RenderCopy(MainRenderer,tPlayer,NULL,NULL);

    Player.Render();                                    //This would be the render funtion

    SDL_RenderPresent(MainRenderer);

}

void CGame::OnCleanup()
{
    SDL_FreeSurface (MainWindowSurface);
    SDL_DestroyWindow (MainWindow);
    SDL_DestroyRenderer (MainRenderer);

    SDL_Quit ();
}

int CGame::GetScreenHeight()
{
    return SCREEN_HEIGHT;
}

int CGame::GetScreenWidth()
{
    return SCREEN_WIDTH;
}

SDL_Renderer* CGame::GetRenderer()
{
    return MainRenderer;
}

/*SDL_Event* CGame::GetEvent()
{
    return MainEvent;
}*/


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
//CSprite.h

#ifndef _CSPRITE_H_
    #define _CSPRITE_H_

#include "SDL.h"
#include "SDL_image.h"


class CGame;


class CSprite
{
    public:
        CSprite();

    public:
        void Load(const char* cPath, int R, int G, int B);
        void Render ();

    private:
        SDL_Rect rcDest;
        SDL_Surface* sImage;
        SDL_Texture* tImage;

        CGame* Game;

};

#endif // _CSPRITE_H_  



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
//CSprite.cpp

#include "CSprite.h"
#include "CGame.h"
#include <iostream>

CSprite::CSprite()
{
    sImage = NULL;
    tImage = NULL;
}


void CSprite::Load (const char* cPath, int R, int G, int B)
{
    sImage = IMG_Load(cPath);
    if (sImage == NULL)
    {
        std::cout << "Fehler beim Laden von " << cPath << "! SDL_Error: " << SDL_GetError() << "\n";
    }
    else
    {
        SDL_SetColorKey(sImage, SDL_TRUE, SDL_MapRGB(sImage-> format, R, G, B));
        tImage = SDL_CreateTextureFromSurface(Game->GetRenderer(), sImage);                       //<-- Thats what you mean
        if (tImage == NULL)
        {
            std::cout << "Fehler beim Umwandeln von einer Surface in eine Textur der Grafik " << cPath << "! SDL_Error: " << SDL_GetError() <<"\n";
        }
        SDL_FreeSurface (sImage);
    }
}


void CSprite::Render()
{
    SDL_RenderCopy (Game->GetRenderer(),tImage,NULL,&rcDest);
}



1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
//CPlayer.h
#ifndef _CPLAYER_H_
    #define _CPLAYER_H_


#include "CSprite.h"


class CPlayer
{
    public:
        CPlayer();

    public:
        void Init();
        void Render();


    private:
        CSprite SpritePlayer;


};

#endif // _CPLAYER_H_  


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
//CPlayer.cpp

#include "CPlayer.h"
#include "CGame.h"



CPlayer::CPlayer()
{

}

void CPlayer::Init()
{
    SpritePlayer.Load("data/imgs/player/Ash_Sprite.bmp", 255, 0, 255);
}


void CPlayer::Render()
{
    SpritePlayer.Render();
} 


Any help appreciated... HalfNOoB
You have a couple of ways to fix this.

1) The evil way to fix this is to get rid of the Game * pointer in the CSprite class and simply reference the global Game, changing CSprite::load as follows:
 
tImage = SDL_CreateTextureFromSurface(Game.GetRenderer(), sImage);                       


2) Disch already explained and gave you a sample of passing a CGame pointer is CSprite's constructor and initializing the Game pointer in the CSprite object.
1
2
3
4
5
CSprite::CSprite (CGame * thegame)
{   Game = thegame;  // make your pointer point to whatever CGame object was supplied
    sImage = NULL;
    tImage = NULL;
}

This is the better approach since it avoids the use of globals, but it's not clear how many places in your code you create CSprite objects.

BTW, I think one of the reasons this was not intuitive to find, was that your global Game variable and your CSprite member variable had the same name.


Hmmmm but I create the Object of "CSprite" in my "CPlayer"-class and there isn't any "CGame" object to pass as an Argument in the "CSprite" -constructer O_o or am I wrong maybe?

I know it's expected a bit much, but could someone tell me where to alter my code so it works? Maybe I'll understand then what Disch and AbstractionAnon want to explain me (although I start thinking I'm way too dumb)...

@AbstractionAnon:
At your first Suggestion: If possible, I'd like to not reference the global Game, but if I don't find any other way I'll have to do it that way...
main generates CPlayer
CPlayer generates CSprite

so main would have to pass the CGame object to CPlayer
CPlayer would then forward that object to CSprite


Though this is questionable design. CSprite probably shouldn't need to know anything about CGame. It looks like all it needs is the SDL renderer... and only for loading/drawing.

So let's back this up. Take CGame out of CSprite entirely, and pass the renderer to whatever functions need it as a parameter. That'll simply things.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
class CPlayer
{
    public:
        CPlayer();

    public:
        void Init(SDL_Renderer* renderer);  // <- pass the renderer to CPlayer
        void Render(SDL_Renderer* renderer);

// ...

class CSprite
{
    public:
        CSprite();

    public:
        void Load(SDL_Renderer* renderer, const char* cPath, int R, int G, int B);
        void Render (SDL_Renderer* renderer); // <- then to CSprite 


Then instead of using Game->GetRenderer... you can just use the renderer passed to the function.
Topic archived. No new replies allowed.