Thread: SDL: Image want load because of the following code?:

  1. #1
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171

    SDL: Image want load because of the following code?:

    Hi C++/SDL programmers! I'm reading the book SDL Game Development and everything where working fine until I came to this point when they wanted me to create many classes to make it as easy as possible to load a image onto the screen in one line of code.

    But I'm stuck with how to get the image to show onto the screen. I have checked that I'm using the correct path for the image in the directory serveral times and the extensions such as .png, .jpg and more . . .

    So I guess something is wrong with the code. One problem is that it is many serparate files and I don't know if this is the right place to ask someones to help me out with this.

    I'm using Code::Blocks with MinGW if somebody wonder about which compiler I'm using.

    This is how the image looks like that I'm trying to load:
    SDL: Image want load because of the following code?:-animate-alpha-png

    If anyone responds to this. I'll like to thank them for their help!

    Here comes the code:

    Game.h
    Code:
    #include <iostream>
    #include <vector>
    #include "SDL.h"
    #include "TextureManager.h"
    #include "GameObject.h"
    #include "Player.h"
    
    
    using namespace std;
    
    
    #ifndef GAME_H_INCLUDED
    #define GAME_H_INCLUDED
    
    
    class Game
    {
        public:
            static Game* Instance()
            {
                if (s_pInstance == 0)
                {
                    s_pInstance = new Game();
                }
                return s_pInstance;
            }
    
    
            bool init(const char* title, int x, int y, int w, int h, int flags);
            void handleEvents();
            void draw();
            void update();
            void render();
            void clean();
    
    
            bool running() {return m_bRunning;}
    
    
            SDL_Renderer* getRenderer() const {return m_pRenderer;}
    
    
        private:
            Game() {}
            ~Game() {}
    
    
            static Game* s_pInstance;
    
    
            SDL_Window* m_pWindow;
            SDL_Renderer* m_pRenderer;
    
    
            bool m_bRunning;
    
    
            int m_currentFrame;
    
    
            vector<GameObject*> m_gameObjects;
    };
    
    
    typedef Game TheGame;
    
    
    #endif // GAME_H_INCLUDED
    Game.cpp
    Code:
    #include <iostream>
    #include <vector>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "Game.h"
    #include "TextureManager.h"
    #include "Enemy.h"
    
    
    using namespace std;
    
    
    Game* Game::s_pInstance = 0;
    
    
    bool Game::init(const char* title, int x, int y, int w, int h, int flags)
    {
        // Init SDL
        if (SDL_Init(SDL_INIT_EVERYTHING) >= 0)
        {
            cout << "SDL init success!\n";
    
    
            // Init the window
            this->m_pWindow = SDL_CreateWindow(title, x, y, w, h, flags);
    
    
            if (this->m_pWindow != 0) // Window init success
            {
                cout << "Window creation success!\n";
                this->m_pRenderer = SDL_CreateRenderer(this->m_pWindow, -1, 0);
    
    
                if (this->m_pRenderer != 0) // Renderer init success
                {
                    cout << "Renderer creation success!\n";
                    SDL_SetRenderDrawColor(this->m_pRenderer, 0, 255, 0, 255);
    
    
                    TheTextureManager::Instance()->load("assets/animate-alpha.png", "animate", this->m_pRenderer);
                    this->m_gameObjects.push_back(new Player(new LoaderParams(100, 100, 128, 82, "animate")));
                    this->m_gameObjects.push_back(new Enemy(new LoaderParams(300, 300, 128, 82, "animate")));
                }
                else
                {
                    cout << "Renderer init fail!\n";
                    return false;
                }
            }
            else
            {
                cout << "Window init fail!\n";
                return false;
            }
        }
        else
        {
            cout << "SDL init fail!\n";
            return false;
        }
        cout << "Init success!\n";
        this->m_bRunning = true; // Everything initialize successfully. Start the main loop
        return true;
    }
    
    
    void Game::draw()
    {
    
    
    }
    
    
    void Game::render()
    {
        SDL_RenderClear(this->m_pRenderer);
        SDL_RenderPresent(this->m_pRenderer);
    }
    
    
    void Game::clean()
    {
        cout << "Cleaning game . . .\n";
        SDL_DestroyWindow(this->m_pWindow);
        SDL_DestroyRenderer(this->m_pRenderer);
        SDL_Quit();
    }
    
    
    void Game::handleEvents()
    {
        SDL_Event event;
        if (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
                case SDL_QUIT: this->m_bRunning = false; break;
                default: break;
            }
        }
    }
    
    
    void Game::update()
    {
    
    
    }
    So this is the class for the "Game". The class that runs the program in the main.cpp file:

    main.cpp
    Code:
    #include <iostream>
    #include "SDL.h"
    
    
    #include "Game.h"
    #include "TextureManager.h"
    #include "Player.h"
    
    
    using namespace std;
    
    
    int main(int argc, char* argv[])
    {
        if (TheGame::Instance()->init("Fails to renderer?!", SDL_WINDOWPOS_CENTERED, SDL_WINDOWPOS_CENTERED, 640, 480, SDL_WINDOW_FOREIGN))
        {
            while (TheGame::Instance()->running())
            {
                TheGame::Instance()->handleEvents();
                TheGame::Instance()->update();
                TheGame::Instance()->render();
                SDL_Delay(10);
            }
            TheGame::Instance()->clean();
        }
        return 0;
    }
    The main.cpp file uses the functions of the Game.h class to make the program run.

    Then I needed something to load and draw images with so then the book learnt me how to create a texture manager.

    TextureManager.h
    Code:
    #include <iostream>
    #include <map>
    #include "SDL.h"
    
    
    using namespace std;
    
    
    #ifndef TEXTUREMANAGER_H_INCLUDED
    #define TEXTUREMANAGER_H_INCLUDED
    
    
    class TextureManager
    {
        public:
            static TextureManager* Instance()
            {
                if (s_pInstance == 0)
                {
                    s_pInstance = new TextureManager();
                }
                return s_pInstance;
            }
    
    
            bool load(string fileName, string id, SDL_Renderer* pRenderer);
            void draw(string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip);
            void drawFrame(string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
    
    
        private:
            TextureManager() {}
            ~TextureManager() {}
            static TextureManager* s_pInstance;
    
    
            map<string, SDL_Texture*> m_textureMap;
    };
    
    
    typedef TextureManager TheTextureManager;
    
    
    #endif // TEXTUREMANAGER_H_INCLUDED
    TextureManager.cpp
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "SDL_image.h"
    #include "TextureManager.h"
    
    
    using namespace std;
    
    
    TextureManager* TextureManager::s_pInstance = 0;
    
    
    bool TextureManager::load(string fileName, string id, SDL_Renderer* pRenderer)
    {
        SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
    
    
        if (pTempSurface == 0)
        {
            return false;
        }
    
    
        SDL_Texture* pTexture = SDL_CreateTextureFromSurface(pRenderer, pTempSurface);
    
    
        SDL_FreeSurface(pTempSurface);
    
    
        // Everything went ok. Add the texture to the list
        if (pTexture != 0)
        {
            this->m_textureMap[id] = pTexture;
            return true;
        }
        // If reaching here. Something went wrong
        return false;
    }
    
    
    void TextureManager::draw(string id, int x, int y, int width, int height, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
    {
        SDL_Rect srcRect;
        SDL_Rect dstRect;
    
    
        srcRect.x = 0;
        srcRect.y = 0;
        srcRect.w = dstRect.w = width;
        srcRect.h = dstRect.h = height;
        dstRect.x = x;
        dstRect.y = y;
    
    
        SDL_RenderCopyEx(pRenderer, this->m_textureMap[id], &srcRect, &dstRect, 0, 0, flip);
    }
    
    
    void TextureManager::drawFrame(string id, int x, int y, int width, int height, int currentRow, int currentFrame, SDL_Renderer* pRenderer, SDL_RendererFlip flip)
    {
        SDL_Rect srcRect;
        SDL_Rect dstRect;
    
    
        srcRect.x = width * currentFrame;
        srcRect.y = height * (currentRow - 1);
        srcRect.w = dstRect.w = width;
        srcRect.h = dstRect.h = height;
        dstRect.x = x;
        dstRect.y = y;
    
    
        SDL_RenderCopyEx(pRenderer, this->m_textureMap[id], &srcRect, &dstRect, 0, 0, flip);
    }
    So this is the class that will have the functions to load a image and I used the load and draw functions from it earlier in the book and then it worked fine. It's just now when I'm going to seperate the code more to make it easier I don't get it to work

    The first thing that the book said I was going to do was a abstract GameObject class:
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "LoaderParams.h"
    
    
    using namespace std;
    
    
    #ifndef GAMEOBJECT_H_INCLUDED
    #define GAMEOBJECT_H_INCLUDED
    
    
    // The abstract base class
    class GameObject
    {
        public:
            // Implement the base class functions
            virtual void draw()=0;
            virtual void update()=0;
            virtual void clean()=0;
    
    
        protected:
            GameObject(const LoaderParams* pParams) {}
            virtual ~GameObject() {}
    };
    
    
    #endif // GAMEOBJECT_H_INCLUDED
    If somebody wonders:
    GameObject.cpp
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "TextureManager.h"
    #include "GameObject.h"
    
    
    using namespace std;
    And then create a derived class that inherits from the GameObject class:

    SDLGameObject.h
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "LoaderParams.h"
    #include "GameObject.h"
    
    
    using namespace std;
    
    
    #ifndef SDLGAMEOBJECT_H_INCLUDED
    #define SDLGAMEOBJECT_H_INCLUDED
    
    
    // Create the class that will load the images onto the screen
    class SDLGameObject : public GameObject
    {
        public:
            SDLGameObject(const LoaderParams* pParams);
    
    
            virtual void draw();
            virtual void update();
            virtual void clean();
    
    
        protected:
    
    
            // Create the private member variables that is used to translate the image
            int m_x;
            int m_y;
    
    
            int m_width;
            int m_height;
    
    
            int m_currentRow;
            int m_currentFrame;
    
    
            string m_textureID;
    };
    
    
    #endif // SDLGAMEOBJECT_H_INCLUDED
    SDLGameObject.cpp
    Code:
    #include <iostream>
    #include "Game.h"
    #include "TextureManager.h"
    #include "SDLGameObject.h"
    
    
    using namespace std;
    The SDLGameObject functions are defined in a class called LoaderParams instead (I don't know why? But the book told me to define them there?):

    LoaderParams.h
    Code:
    #include <iostream>
    #include "SDL.h"
    
    
    using namespace std;
    
    
    #ifndef LOADERPARAMS_H_INCLUDED
    #define LOADERPARAMS_H_INCLUDED
    
    
    class LoaderParams
    {
        public:
            // Create a constructor that inherits the member variables
            LoaderParams(int x, int y, int width, int height, string textureID) : m_x(x), m_y(y), m_width(width), m_height(height), m_textureID(textureID) {}
    
    
            // Create the functions to access the private member variables set from the constructor
            int getX() const {return m_x;}
            int getY() const {return m_y;}
            int getWidth() const {return m_width;}
            int getHeight() const {return m_height;}
            string getTextureID() const {return m_textureID;}
    
    
        private:
            int m_x;
            int m_y;
    
    
            int m_width;
            int m_height;
    
    
            string m_textureID;
    };
    
    
    #endif // LOADERPARAMS_H_INCLUDED
    So it's in the .cpp file them are defined:
    LoaderParams.cpp
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "Game.h"
    #include "TextureManager.h"
    #include "GameObject.h"
    #include "LoaderParams.h"
    #include "SDLGameObject.h"
    
    
    using namespace std;
    
    
    // Define the constructor and inherit the GameObject constructor and pass in the LoaderParams* pParams pointer variable
    SDLGameObject::SDLGameObject(const LoaderParams* pParams) : GameObject(pParams)
    {
        this->m_x = pParams->getX();
        this->m_y = pParams->getY();
    
    
        this->m_width = pParams->getWidth();
        this->m_height = pParams->getHeight();
    
    
        this->m_textureID = pParams->getTextureID();
    
    
        this->m_currentRow = 1;
        this->m_currentFrame = 1;
    }
    
    
    void SDLGameObject::draw()
    {
        // Get the TextureManager drawFrame() function to draw images onto the screen
        TextureManager::Instance()->drawFrame(this->m_textureID, this->m_x, this->m_y, this->m_width, this->m_height, this->m_currentRow, this->m_currentFrame, TheGame::Instance()->getRenderer(), SDL_FLIP_NONE);
    }
    
    
    void SDLGameObject::update()
    {
    
    
    }
    
    
    void SDLGameObject::clean()
    {
    
    
    }
    So now over to the important part of this. Here is the class for the player called Player

    Player.h
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "LoaderParams.h"
    #include "SDLGameObject.h"
    
    
    using namespace std;
    
    
    #ifndef PLAYER_H_INCLUDED
    #define PLAYER_H_INCLUDED
    
    
    class Player : public SDLGameObject
    {
        public:
            Player(const LoaderParams* pParams);
    
    
            virtual void draw();
            virtual void update();
            virtual void clean();
    };
    
    
    #endif // PLAYER_H_INCLUDED
    Player.cpp
    Code:
    #include <iostream>
    #include "SDL.h"
    #include "SDLGameObject.h"
    #include "Player.h"
    
    
    using namespace std;
    
    
    // Define the construtor of the Player class to create the player
    Player::Player(const LoaderParams* pParams) : SDLGameObject(pParams)
    {
    
    
    }
    
    
    // Define the function that will draw the image onto the screen
    void Player::draw()
    {
        SDLGameObject::draw(); // Use the SDLGameObject draw function that includes the TextureManager draw function and the Game class renderer
    }
    
    
    void Player::update()
    {
        this->m_x -= 1;
        this->m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
    }
    
    
    void Player::clean()
    {
    
    
    }

  2. #2
    Registered User MutantJohn's Avatar
    Join Date
    Feb 2013
    Posts
    2,665
    I know this isn't a helpful post but holy poop is that a lot of code O_o

  3. #3
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Haha yeah, It is! . But it would be even better if I could get it to work. The only problem with the code is that it won't load a image

  4. #4
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    you totally did not need to post all that code, you have 77 posts you should know that. Tell us what happens when you run the game - does it just show a black screen, what?
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  5. #5
    Registered User
    Join Date
    Nov 2012
    Posts
    1,393
    Quote Originally Posted by DecoratorFawn82 View Post
    Haha yeah, It is! . But it would be even better if I could get it to work. The only problem with the code is that it won't load a image
    Look at this line

    Code:
    SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());
    What happens when IMG_Load fails? You're checking the return value in the function but you're not doing anything useful if it fails. I believe there's a function in the SDL API for telling you more about what went wrong with files kind of similar to how perror works in the standard library. Look in the header file where IMG_Load is defined.

  6. #6
    Registered User rogster001's Avatar
    Join Date
    Aug 2006
    Location
    Liverpool UK
    Posts
    1,472
    c99 _ Mate i like your post but this is code that has been wholesale copied and dumped without comprehension, call me a cynic
    Thought for the day:
    "Are you sure your sanity chip is fully screwed in sir?" (Kryten)
    FLTK: "The most fun you can have with your clothes on."

    Stroustrup:
    "If I had thought of it and had some marketing sense every computer and just about any gadget would have had a little 'C++ Inside' sticker on it'"

  7. #7
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    Okay, I will try to edit it and make it more clear what I'm creating

  8. #8
    Registered User
    Join Date
    Feb 2013
    Location
    Sweden
    Posts
    171
    But it would really help if someone has read the book: SDL Game Development and chapter 3 from page 62. That's where I got stuck.

  9. #9
    Registered User
    Join Date
    Sep 2014
    Posts
    13

    is that solved?

    Hi there, I'm working with that book and stick at same chapter.. I searched the whole day, why it isn't working.. Did someone find the solution?

  10. #10
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    I've read the entire book, and I hate to be the bearer of bad news, but the code in parts of that book are completely broken. However you won't hit very hard times until you come to the statemachine chapter. There are a few problems with the vector class as well (it's only an allocation problem, you will notice how he does nearly everything on the heap).

    When you do get to the statemachine chapter, if you want I can give you some workarounds for the problem.

    You posted way too much code for me to look through, if you run a debugger and tell me exactly where it's crashing, I will take a look and help you out.

    @Sonntag69 - I just noticed this was a post from like a year ago... So I'll just extend my offer to you instead. Just run the debugger and tell me where the program is stalling or whatever. If you need help organizing (the author doesn't tell you what to #include I know), I can help with that as well, but I need more info than either you or the original poster gave me :P.
    Last edited by Alpo; 09-05-2014 at 10:10 PM.

  11. #11
    Registered User
    Join Date
    Sep 2014
    Posts
    13
    Quote Originally Posted by Alpo View Post
    @Sonntag69 - I just noticed this was a post from like a year ago... So I'll just extend my offer to you instead. Just run the debugger and tell me where the program is stalling or whatever. If you need help organizing (the author doesn't tell you what to #include I know), I can help with that as well, but I need more info than either you or the original poster gave me :P.

    Hi Alpo, at first, thank you for the information, that it would get harder in the following chapters :-).
    It´s really confusing what the Author does. The Debbuger didn´t tell me anything at the moment, what could make problems. After searching mistakes for more than 10 hours I decided to build up his "chapter 3" by myself.. very slowly.. so first step was to copy his LoaderParameters.h. and then use them to construct a player. The values in the debugger told me, that that worked fine. But it don´t draw the player on the screen.. My mainproblem is time. I´m working on a projekt and have only 4 Workdays left to go through this book and understand, what he does. So it could help me a lot, if I would have a working code from each chapter. So that I could learn from working code. Perhaps you have the working code from each chapter since chapter 3? That would be sooo helpful for me.

    Best Regards

    Sonntag

  12. #12
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Sonntag69 View Post
    Hi Alpo, at first, thank you for the information, that it would get harder in the following chapters :-).
    It´s really confusing what the Author does. The Debbuger didn´t tell me anything at the moment, what could make problems. After searching mistakes for more than 10 hours I decided to build up his "chapter 3" by myself.. very slowly.. so first step was to copy his LoaderParameters.h. and then use them to construct a player. The values in the debugger told me, that that worked fine. But it don´t draw the player on the screen.. My mainproblem is time. I´m working on a projekt and have only 4 Workdays left to go through this book and understand, what he does. So it could help me a lot, if I would have a working code from each chapter. So that I could learn from working code. Perhaps you have the working code from each chapter since chapter 3? That would be sooo helpful for me.

    Best Regards

    Sonntag
    I do have code from the book through several stages (where I would make a save of the folder as a checkpoint), but it isn't really divided by chapters, but the first of those I have is a bit ahead of where you are, when I first became aware of the problems with the code. Also the farther I went in the book, the more changes I was making, so I'm not sure if my code could help.

    If I'm getting you correctly, your program is not crashing, but is just not drawing the character to the screen? Were you able to draw a sprite before you implemented the Inheritance structure and LoaderParams?

    Assuming so, Have you tried running the debugger on the SDLGameObject::draw() function?

    You should see an m_currentRow value of 1, and an m_currentFrame value looping from 1 through 5 (or however many frames, I can't remember). Check to make sure the m_height and m_width values are correct for the sprite (you may want to measure the sprite yourself, I use GIMP for that sort of thing), and that the m_textureID is the same as you have registered with the TextureManager.
    Edit: You can also get the height & width of the entire texture from the temp SDL_Surface in TextureManager::LoadImage() before it is destroyed (if you do that you will need to divide by the number of Rows and Frames to get the correct frame width and height).

    If you still can't get it to show, check the TextureManager:: DrawFrame() function, which should look something like this:

    Code:
    void texture_manager::drawFrame(std::string id, int x, int y, int width, int height, int currentrow,  int currentframe, SDL_Renderer* pRender, SDL_RendererFlip flip)
    {
        SDL_Rect srcRect, destRect;
    
        srcRect.x = width * currentframe;
    
        srcRect.y = height * (currentrow - 1);
    
        srcRect.w = destRect.w = width;
    
        srcRect.h = destRect.h = height;
    
        destRect.x = x; destRect.y = y;
    
        SDL_RenderCopyEx(pRender, m_textureMap[id], &srcRect, &destRect, 0, 0, flip);
    }
    Make sure that the currentrow is being subtracted by 1, as the author uses this to calibrate the beginning position for the m_currentRow value of GameObjects to start at 1 (without it, you will be overshooting the sprites position and not getting anything on the screen).


    If none of this is working, go and check the Game::m_GameObjects vector and make sure it contains the number of GameObjects you are working with (1 probably).

    Also check the TextureManager::m_TextureMap map and make sure it has the correct values set (The key field must be set to the same string as GameObject::m_TextureID, this is what allows the TextureManager to access the SDL_Texture associated with the sprite). You can use an iterator to loop through the map to do this.

    That about all I can think of that could be causing problems at this stage in the book. I do think you are going to need more than 4 days, it took me about 2-3 weeks just to get to the end, and I was going fast (it takes some extra time to work out bugs and the like, as you know).
    Last edited by Alpo; 09-06-2014 at 01:32 PM.

  13. #13
    Registered User
    Join Date
    Sep 2014
    Posts
    13

    Smile

    Quote Originally Posted by Alpo View Post
    I do have code from the book through several stages (where I would make a save of the folder as a checkpoint), but it isn't really divided by chapters, but the first of those I have is a bit ahead of where you are, when I first became aware of the problems with the code. Also the farther I went in the book, the more changes I was making, so I'm not sure if my code could help.

    If I'm getting you correctly, your program is not crashing, but is just not drawing the character to the screen? Were you able to draw a sprite before you implemented the Inheritance structure and LoaderParams?

    Assuming so, Have you tried running the debugger on the SDLGameObject::draw() function?

    You should see an m_currentRow value of 1, and an m_currentFrame value looping from 1 through 5 (or however many frames, I can't remember). Check to make sure the m_height and m_width values are correct for the sprite (you may want to measure the sprite yourself, I use GIMP for that sort of thing), and that the m_textureID is the same as you have registered with the TextureManager.
    Edit: You can also get the height & width of the entire texture from the temp SDL_Surface in TextureManager::LoadImage() before it is destroyed (if you do that you will need to divide by the number of Rows and Frames to get the correct frame width and height).

    If you still can't get it to show, check the TextureManager:: DrawFrame() function, which should look something like this:

    Code:
    void texture_manager::drawFrame(std::string id, int x, int y, int width, int height, int currentrow,  int currentframe, SDL_Renderer* pRender, SDL_RendererFlip flip)
    {
        SDL_Rect srcRect, destRect;
    
        srcRect.x = width * currentframe;
    
        srcRect.y = height * (currentrow - 1);
    
        srcRect.w = destRect.w = width;
    
        srcRect.h = destRect.h = height;
    
        destRect.x = x; destRect.y = y;
    
        SDL_RenderCopyEx(pRender, m_textureMap[id], &srcRect, &destRect, 0, 0, flip);
    }
    Make sure that the currentrow is being subtracted by 1, as the author uses this to calibrate the beginning position for the m_currentRow value of GameObjects to start at 1 (without it, you will be overshooting the sprites position and not getting anything on the screen).


    If none of this is working, go and check the Game::m_GameObjects vector and make sure it contains the number of GameObjects you are working with (1 probably).

    Also check the TextureManager::m_TextureMap map and make sure it has the correct values set (The key field must be set to the same string as GameObject::m_TextureID, this is what allows the TextureManager to access the SDL_Texture associated with the sprite). You can use an iterator to loop through the map to do this.

    That about all I can think of that could be causing problems at this stage in the book. I do think you are going to need more than 4 days, it took me about 2-3 weeks just to get to the end, and I was going fast (it takes some extra time to work out bugs and the like, as you know).
    Hi Alpo, I just wrote a long text, and it´s gone, because I wasn´t logged in :-).. Damn! :-)..
    In short form again.. :-)... As I wrote the Code in that way, the book wants me to, the compiler didn´t like it.. Strange Errors like "put a ',' between LoaderParams and '*'.. ?? .. lol.. Sound relativly Senseless to me.. So I tried to come to the destination of chapter three on an other way.. first including LoaderParams.. without making Gameobject abstract.. I would like to go step by step by getting the Code working at each point.. Here I had the Problem, that he didn´t draw the Image on my Display. As I thought I see that the draw-function has the correct parameters.. but I will check it again..
    The Code you have as 'Checkpoints' could help me, I think..
    I have the finished Code from Alien Attak and Conan the Caveman, and these helped me to get through chapter one and two in 3 days.
    But for chapter 3 it wasn´t working.. I think till the End there are to many changes he made..

    It´s all a little difficult for me, because my english isn´t the best one and the book is also difficult aaand.. I´m a relativly newbee.. I had 6 Weeks Java-Training, 2 Weeks Java-Projectwork, 6 Weeks C++ inkl. Visual C++, and at the moment 1 Week Projectweek.. So what I wanted to do in my projectwork is to make a little game with SDL and make checkpoints for each relevant position in the book. So that the others in my course could take that to learn it by themselve, without the problems I had..Till the beginning of Chapter three, I have that. Certainly with german comments :-).. But I think, after that project it would be a nice idea to make the comments in english, too. And than post everything.. So it could help others..

    I think the Code from your checkpoints could help me, and make some things clearer for me..

    For example.. The Loaderparams.h. .. I saw that DecoratorFawn82 had a Loaderparams.cpp, too.. In the Endcode of Alienattack there wasn´t Loaderparams.cpp.. Is that necassary?
    Second Question is, if I make Gameobject to an abstract class.. do I need the Gameobject.cpp anymore?

    But enough to read for now :-).. I will now check your hints, with my first Step (inluding LoaderParams).. :-)..
    And maybe I wasn´t right with, that I think, I got it, with the includings.. Like I said.. I´m relativly newbee :-)

    Best Regards and thanks a lot for your help and hints :-)

    Sonntag69

  14. #14
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Sonntag69 View Post
    For example.. The Loaderparams.h. .. I saw that DecoratorFawn82 had a Loaderparams.cpp, too.. In the Endcode of Alienattack there wasn´t Loaderparams.cpp.. Is that necassary?
    Second Question is, if I make Gameobject to an abstract class.. do I need the Gameobject.cpp anymore?

    But enough to read for now :-).. I will now check your hints, with my first Step (inluding LoaderParams).. :-)..
    And maybe I wasn´t right with, that I think, I got it, with the includings.. Like I said.. I´m relativly newbee :-)

    Best Regards and thanks a lot for your help and hints :-)

    Sonntag69

    What to #include was a problem for me as well. Check this article out, if you follow the guidelines of what to #include listed there, you can make it to the end of the book no problem:

    Headers and Includes: Why and How - C++ Forum

    As for whether or not LoaderParams or GameObject needs a source file. I would say GameObject definitely does not. The only object GameObject makes reference to at this point is LoaderParams, which it uses in pointer form, so the GameObject header doesn't need any #includes, only a forward declaration of LoaderParams:

    Code:
    /// At top of GameObject.h :
    
    class LoaderParams;
    LoaderParams could or could not. My thinking on it is that at this point in the book it does not, as the only object it contains is a std::string, and it would still contain a std::string even if you moved all the function definitions to a source file. So you would still need to #include <string> in the header, even if you moved everything else to the source file. Later on, if you need more complicated objects in your LoaderParams, then it might be an advantage to create a source file for it.

    The one class you might consider giving it's own source file to is the Vector2D class. As it is needed in almost every other file, and one of it's functions relies on <cmath>, it might be an advantage to move everything requiring <cmath> to a source file. This would just be to get the #include out of the header (which is usually a good idea). It's not strictly necessary though, just a thought.

    I will try to get those files to you. I don't really know where I could upload them right now, I'll PM you in a while once I've figured it out. You will need to rewrite the player and enemy logic, and also go into Game::Init() and change the directory for the image file.

    If you do that, you should be good to go. However, I would encourage you to just do a comparison with what you already have, and change what is necessary.

  15. #15
    Registered User
    Join Date
    Sep 2014
    Posts
    13

    Thumbs up a lot of Code (Polymorphism - just working)

    End of chapter 2 - Polymorphism (till Side 60 without making GameObject abstract...
    (where it´s working/Comments unfortunately only in German :-)):

    main.cpp
    Code:
    #include <Windows.h>
    #include <iostream>
    #include "Game.h"
    
    // Globale Variablen
    
    Game* g_game = 0; // Zeiger für ein zu erzeugendes Spielfeld-Objekt (mit 0 initialisiert)
    
    int main(int argc, char* argv[])
    {
    // Instanz erstellen
        g_game = new Game();
    
    
    // Das Spielefenster dieser Instanz erstellen
         if (g_game->init("Animation-TextureManager als Singelton", 100,  100, 640, 480, false))    // letzter Parameter true = Fullscreen, false =  normales fenster         
                                                                                                                          // Sinn ist, keine SDL-Anweisung in der main zu haben.
    
    
    // Die Spielschleife
        while (g_game->running())
        {
            g_game->handleEvents();
            g_game->update(); // noch nicht benutzt, da keine Physics ausgeführt werden
            g_game->render();
    
            SDL_Delay(10); // --> Wird auf Seite 55 hinzugefügt, damit das Objekt sich nicht zu schnell bewegt
        }
    
    
    
    //Programm aufräumen und beenden
        g_game->clean();
        return 0;
    }
    GameObject.h
    Code:
    //  GameObject.h
    // inheritance = vererben
    // derive = ableiten
    #include <iostream>        // im Buch nicht erwähnt, aber nötig wegen cout
    #include "TextureManager.h" // im Buch nicht erwähnt, aber nötig um den Zeiger pRenderer der Funktion draw nutzen zu können
    
    #ifndef __GameObject___
    #define __GameObject___
    
    class GameObject
    {
    public:
        GameObject(){}
        ~GameObject(){}
    
        virtual void load(                //--> Seite 57 (virtual wird bei allen Funktionen dieser Klasse vorangesetzt) --> 
            int x,                        //                Durch das "virtual" wird, sofern durch einen Zeiger aufgerufen,         
            int y,                        //                die Definition des Objekts benutzt und nicht die, des Zeigers    
            int width, 
            int height, 
            std::string
            textureID);
    
        virtual void draw(                
            SDL_Renderer* pRenderer);
        virtual void update();            
    
        // virtual void clean();    --> Auf Seite 60 hab ich erst gemerkt, das dieses rausgeschmissen 
                                        // werden muss. Wann hab ich nur die Funktion nach Game verlagert?        
    
        
    protected:
    
        std::string m_textureID;
        int m_currentFrame;        // Spalte des Quell-Frames in der Grafikdatei
        int m_currentRow;        // Zeile des Quell-Frames in der Grafikdatei
        int m_x;                // x-Position auf dem Bildschirm, wo das Object platziert wird
        int m_y;                // y-Position auf dem Bildschirm, wo das Object platziert wird
        int m_width;            // Breite des Frames
        int m_height;            // Höhe des Frames
        
    };
    
    #endif
    GameObject.cpp
    Code:
    #include "GameObject.h"
    
    void GameObject::load(int x, int y, int width, int height, std::string
        textureID)
    {
        m_x = x;
        m_y = y;
        m_width = width;
        m_height = height;
        m_textureID = textureID;
        m_currentRow = 1;
        m_currentFrame = 1;
    }
    
    void GameObject::draw(SDL_Renderer* pRenderer)
    {
        TextureManager::Instance()->drawFrame(
            m_textureID, 
            m_x, 
            m_y,
            m_width, 
            m_height, 
            m_currentRow, 
            m_currentFrame, 
            pRenderer);
    }
    
    void GameObject::update()
    {
        m_x += 1;
         m_currentFrame = int(((SDL_GetTicks() / 100) % 6)); // --> Seite 45  wurde dies bei Game::update eingefügt. Aber später vergessen
                                                             //     in die Klasse  GameObject mit zu übernehmen. Somit fand keine Animation
                                                             //       von "GameObject  m_go" statt. Im  Gegensatz wird die Animation von
                                                             //       "Player m_player" in  Player::Update realisiert, da es ein Objekt der
                                                             //       Kindklasse "Player" ist  und nicht direkt von GameObjekt instanziiert 
                                                            //     wurde. Leider wurde dies im Buch völlig vergessen, so dass keine 
                                                            //     Animation zu sehen war.
    }
    Game.h
    Code:
    #ifndef __Game__            // Falls Game noch nicht definiert wurde.....
    #define __Game__            // .... dann definiere Game so.....
    
    #include<SDL.h>                //Einbindung der SDL-Bibliothek
    #include<SDL_image.h>
    #include "TextureManager.h" // Texturemanager wird eingebunden --> Seite 45
    #include  "GameObject.h"        // --> im Buch nicht erwähnt (muss ab Seite 54  hinzugefügt werden um Gameobject m_go zu erstellen)
    #include  "Player.h"            // --> im Buch nicht erwähnt (muss ab Seite 54  hinzugefügt werden um Player m_player zu erstellen)
    #include  "Enemy.h"            // --> im Buch nicht erwähnt (muss ab Seite 56  hinzugefügt werden um Player m_player zu erstellen)
    #include  <vector>            // --> im Buch nicht erwähnt ( muss ab  Seite 54 hinzugefügt werden, um einen Vector für Gameobjekte zu  erstellen)
    
    class Game
    {
    public:
        Game() {}            // Konstruktor
        ~Game() {}            // Destruktor
    
        //Klassenmember
        GameObject* m_go; //    --> Seite 58 (wird in einen Zeiger verwamdelt durch das '*'-Symbol
        GameObject* m_player; //--> Seite 58 (wird hinzugefügt)
         // Player m_player; --> muss ab Seite 56 ausdokumentiert werden, da  sich das mit dem Zeiger "GameObject* m_player" beißt und in der
                                // Game.cpp dann auch "m_player" unterstrichen wird
    
    
        // Neue Gameobjekte --> Seite 56
    
        
        GameObject* m_enemy; // --> Wird erst auf Seite 59 hinzugefügt
        GameObject* m_enemy1;
        GameObject* m_enemy2;
        GameObject* m_enemy3;
    
    
        // Abbruchvariable (zum unterbrechen der Spielschleife)    
        bool running() { return m_bRunning; }
    
         std::vector<GameObject*> m_gameObjects; // --> Seite 56 + 58  (Vorsicht!!! wurde vom Autor versehentlich 2 mal eingefügt)
    
        // Funktionsliste
        bool init(const char* title, int xpos, int ypos, int
            width, int height, bool fullscreen);
    
        void init();
        void render();
        void update();
        void handleEvents();
        void clean();
         void draw(); // --> neue Funktion, die auf Seite 56 eingeführt wird  (Laut buch, nur in Game.cpp. Das schreiben in die Game.h wurde nicht  erwähnt)
    
        
    
    // Diese Zeiger und Attribute können nur einmal erstellt werden, da Game nur einmal erstellt werden kann und von außerhalb 
    // kein Zugriff auf die privaten Attribute und Zeiger gestattet ist.
    private:
        SDL_Window* m_pWindow;                // Ein Zeiger wird erstellt, dem das zu erstellende Fenster zugeordnet werden kann
         SDL_Renderer* m_pRenderer;            // Ein Zeiger wird erstellt, dem  das zu erstellende Renderobjekt zugeordnet werden kann
        //  SDL_Texture* m_pTexture;            // Ein Zeiger wird erstellt, dem ein  Textureobjekt zugeordnet werden kann --> Wird rausgeschmissen, weil  jetzt 
                                            // Über den Texturemanager geladen wird --> Seite 45
    
        SDL_Rect m_sourceRectangle;            // Ein Zeiger wird erstellt, dem ein Quellviereck für Grafik zugeordnet werden kann
         SDL_Rect m_destinationRectangle;    // Ein Zeiger wird erstellt, dem  dem ein Zielviereck für Grafik auf dem virtuellen Bildschirm zugeordnet  werden kann
    
        bool m_bRunning;
        int m_currentFrame;
        TextureManager* Instance();    // Hier wird ein Objekt des TextureManagers erstellt --> Seite 44
    
    };
    #endif /* defined(__Game__) */
    Game.cpp
    Code:
    #include "Game.h"
    #include <iostream>
    
    
    using namespace std;
    
    
    bool Game::init(const char* title, int xpos, int ypos, int width,
        int height, bool fullscreen)
    {
        // SDL soll initialisiert werden
        if (SDL_Init(SDL_INIT_EVERYTHING) == 0)
        {
            cout << "SDL wurde erfolgreich initialisiert" << endl;
                // Zur unterscheidung zwischen Fullscreen oder Fenstermodus
                int flags = 0;
                if (fullscreen)
                {
                    flags = SDL_WINDOW_FULLSCREEN;
                }
            
            // Fenster wird initialisiert
                cout << "Fenster wird initialisiert" << endl;
            m_pWindow = SDL_CreateWindow(title, xpos, ypos,
                width, height, flags);
            
            if (m_pWindow != 0) // Wenn Fensterinitialisierung erfolgreich wird der Renderer initialisiert
            {
                cout << "Fenster wurde erfolgreich initialisiert" << endl;
                cout << "Renderer wird initialisiert" << endl;
                m_pRenderer = SDL_CreateRenderer(m_pWindow, -1, 0);
                if (m_pRenderer != 0) // Wenn die Rendererinitialisierung erfolgreich war
                {
                    cout << "Renderer wurde erfolgreich initialisiert" << endl;
                    SDL_SetRenderDrawColor(m_pRenderer, // Hintergrundfarbe wird gesetzt (RGB/A)
                        255, 0, 0, 255);
    
    
                    if ((IMG_Init(IMG_INIT_PNG) & IMG_INIT_PNG) != IMG_INIT_PNG)
                    {
                        
                        SDL_Quit();
                        return 1;
                    }
                    else
                    {
                        cout << "IMG_Init wurde erfolgreich mit PNG - Format initialisiert" << endl;
                    }
    
                    
    
                }
                else
                {
                    
                    return false; // Rendererinitialisierung fehlgeschlagen
                }
            }
            else
            {
                
                return false; // Fensterinitialisierung fehlgeschlagen
            }
        }
        else
        {
            
            return false; // SDLinitialisierung fehlgeschlagen
        }
        cout << "Alles initialisiert" << endl;
        
        
        if (!TheTextureManager::Instance()->load("Data/animate-alpha.png",
            "animate", m_pRenderer))
        {
            return false;
            cout << "Fehler beim Datei Laden" << endl;
        }
    
         // m_go.load(100, 100, 128, 82, "animate");        // --> Seite 54  --> "animate" = TextureID --> wurde wieder eintfernt beim Kapitel  Polymorphismus
        // m_player.load(300, 300, 128, 82, "animate");     // --> kann aufgrund des gleichen Namens wie des eingeführten  Zeigers auf Seite 56 so nicht mehr verwendet werden
        
    
        m_go = new GameObject(); // --> Seite 58
        m_player = new Player(); // --> Seite 56 und 58 (wurde vom Autor versehentlich zweimal beschrieben)
        m_enemy = new Enemy();     // --> wird erst auf Seite 59 hinzugefügt 
        m_enemy1 = new Enemy();     // --> Seite 56 (Zuvor muss aber erst eine Enemy.h erstellt werden, in Game.h
        m_enemy2 = new Enemy(); //      includet und eine Klasse Enemy erstellt werden, die von GameObject erbt
        m_enemy3 = new Enemy(); //        (nicht im Buch)). Diese ist erstmal exakt aufgebaut, wie die Klasse Player
    
        // --> Seite 58 --> Objekte Laden
        m_go->load(100, 100, 128, 82, "animate");
        m_player->load(300, 300, 128, 82, "animate");
        m_enemy->load(0, 0, 128, 82, "animate"); // --> wird erst auf Seite 59 hinzugefügt 
    
    
        // --> Die verschiedenen Gameobjekte werden in das Vektorarray geschoben
        m_gameObjects.push_back(m_go);        // --> Seite 58
        m_gameObjects.push_back(m_player);  // --> Seite 56 und 58 (wurde vom Autor versehentlich zweimal beschrieben)
        m_gameObjects.push_back(m_enemy);   // --> wird erst auf Seite 59 hinzugefügt
        m_gameObjects.push_back(m_enemy1);  // --> Seite 56
        m_gameObjects.push_back(m_enemy2);  // --> Seite 56
        m_gameObjects.push_back(m_enemy3);  // --> Seite 56
        
        m_bRunning = true;    // Initialisierungen waren alle erfolgreich 
                            //Loop-Bool wird auf true gesetzt für die Spielschleife
            return true;
    } // Ende der Initialisierung
    
    
    
    // --> Seite 56 --> neue eingeführte Funktion (es werden alle Objekte des Arrays 
    // durchlaufen und gemalt. Wichtig ist nur, das sie von Gameobject abstammen (Polymorphismus)
    void Game::draw()
    {
        for (std::vector<GameObject*>::size_type i = 0; i !=
            m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->draw(m_pRenderer);
        }
    }
    TextureManager.h
    Code:
    #ifndef __TextureManager__
    #define __TextureManager__
    
    #include <iostream> // --> im Buch nicht erwähnt
    #include <string> // --> im Buch nicht erwähnt
    #include <map> // --> im Buch nicht erwähnt
    #include "SDL.h" // --> im Buch nicht erwähnt
    
    class TextureManager
    {
    public:
    
        // --> eingeführt -->    Seite 42
        bool load(                        // Funktion zum Laden der Grafikdatei
            std::string fileName,        //Filename
            std::string id,                //ID- der zu Rendernden Texture
            SDL_Renderer* pRenderer);    //verwendeter Renderer                                
    
        // draw --> eingeführt -->   Seite 42
         void draw(                                        // Funktion zum  Malen eines feststehenden Frames auf den virtuellen Bildschirm
            std::string id,                                //ID- der zu Rendernden Texture
            int x,                                        // Destination-X
            int y,                                        // Destination-Y
            int width,                                    // Die Breite des zu benutzenden Frames
            int height,                                    // Die Höhe des zu benutzenden Frames
            SDL_Renderer* pRenderer,                    // Der zu benutzende Renderer 
            SDL_RendererFlip flip = SDL_FLIP_NONE);        // Flag zur Angabe, ob das Frame gespiegelt werden soll    
    
        // drawframe --> eingeführt -->    Seite 42
        void drawFrame(std::string id, int x, int y, int width, int
            height, int currentRow, int currentFrame, SDL_Renderer*
            pRenderer, SDL_RendererFlip flip = SDL_FLIP_NONE);
    
        // Funktion zur erzeugung der Singelton-Klasse des Texturemanagers --> Seite 46
        // Nur wenn noch keine Instanz des Texturemanagers exisitiert, wird eine erzeugt. Ansonsten
        // wird die bereits erzeugte zurück gegeben.
        static TextureManager* Instance()
        {
            if (s_pInstance == 0)
            {
                s_pInstance = new TextureManager();
                return s_pInstance;
            }
            return s_pInstance;
        }
    
    
    
    
    
    private:
        TextureManager() {} // --> Um den Texturemanager zu einem Singelton zu machen wird zuerst der Konstruktor 
        // von public zu privat verschoben, somit kann er nur über die Instancefunction
        // aufgerufen werden --> Seite 46
        ~TextureManager() {} // --> im Buch nicht erwähnt
    
    
    
        static TextureManager* s_pInstance; // --> im Buch nicht erwähnt, aber notwendig S.46
    
    
    
        // --> eingeführt -->  Seite 42
        std::map<std::string, SDL_Texture*> m_textureMap;    // Ein container der unsere zu Rendernden Objekte enthält. 
        // gespeichert wird immer ein Wertepaar. Die Objektreferenz 
        // und ein eindeutiger Schlüssel (ID)
        // Speicherart ist üblicherweise ein Red-Black-Tree,
        // ein selbstregulierender binärer Suchbaum.
    
    };
    
    typedef TextureManager TheTextureManager; // --> Seite 46 --> Hier wird ein Aliasname vergeben und überall,
    // wo man Texturemanager schreiben müsste, kann man
    // jetzt genauso TheTextureManager schreiben --> neu zu Texturemanager goes Singelton
    
    #endif
    TextureManager.cpp
    Code:
    #include "TextureManager.h"
    #include "SDL_image.h"
    #include "SDL.h"
    
    
    TextureManager* TextureManager::s_pInstance = 0; // --> eingeführt S.46
    
    // --> eingeführt --> Seite 43
    bool  TextureManager::load(            //Funktion zum Laden der Grafikdatei   und zum zuordnen einer ID in unserem red-black-tree-container (map)
        std::string fileName,            // Filename
        std::string id,                    // zugeordnete FileID im red-black-tree
        SDL_Renderer* pRenderer)        // zu verwendender Renderer
    {
         SDL_Surface* pTempSurface = IMG_Load(fileName.c_str());    // File  wird geladen und ist unter dem Zeiger pTempSurface zu erreichen
    
        if (pTempSurface == 0)                                    // Wenn nicht ladbar
        {                                                        
            std::cout << IMG_GetError();                        // Gebe Fehler aus
            return false;                                        
        }
    
        SDL_Texture* pTexture =                                        // erstelle Zeiger auf ein Texture-Objekt
             SDL_CreateTextureFromSurface(pRenderer, pTempSurface);    //  erstelle das Texture-Objekt, das dem Zeiger pTexture zugeordnet wird
        SDL_FreeSurface(pTempSurface);
        // Datei wurde Ordnungsgemäß geladen und wird nachfolgend unserem red-black-tree-container hinzugefügt
        if (pTexture != 0)
        {
            m_textureMap[id] = pTexture;
            return true;
        }
        // Wenn nicht geladen werden konnte
        return false;
    }
    
    
    // --> eingeführt --> Seite 43
    void TextureManager::draw(        // Funktion zum Malen eines feststehenden Frames auf den virtuellen Bildschirm
        std::string id,                //ID- der zu Rendernden Texture
        int x,                        // Destination-X
        int y,                        // Destination-Y
        int width,                    // Die Breite des zu benutzenden Frames
        int height,                    // Die Höhe des zu benutzenden Frames
        SDL_Renderer* pRenderer,    // Der zu benutzende Renderer 
        SDL_RendererFlip flip)        // Flag zur Angabe, ob das Frame gespiegelt werden soll
    {
        SDL_Rect srcRect;                    // Quell-Viereck wird erstellt
        SDL_Rect destRect;                    // Ziel-Viereck wird erstellt
        srcRect.x = 0;                        // x-Position des oberen linken Ecks des Quellrechtecks
        srcRect.y = 0;                        // y-Position des oberen linken Ecks des Quellrechtecks
        srcRect.w = destRect.w = width;        // Breite des Quell- und Ziel-Rechtecks
        srcRect.h = destRect.h = height;    // Höhe des Quell- und Ziel-Rechtecks
        destRect.x = x;                        // x-Position des oberen linken Ecks des Zielrechtecks auf dem virtuellen Bildschirm
        destRect.y = y;                        // x-Position des oberen linken Ecks des Zielrechtecks auf dem virtuellen Bildschirm
        SDL_RenderCopyEx(                    // Zu verwendender Renderer
            pRenderer, 
            m_textureMap[id],                // ID des Grafikobjekts
            &srcRect,                        // Zeiger auf Quell-Rechteck
            &destRect,                        // Zeiger auf Ziel-Rechteck
            0, 
            0, 
            flip);
    }
    
    
    // --> eingeführt --> Seite 44
    void TextureManager::drawFrame(
        std::string id,                //ID- der zu Rendernden Texture
        int x,                        // Destination-X
        int y,                        // Destination-Y
        int width,                    // Die Breite des zu benutzenden Frames
        int height,                    // Die Höhe des zu benutzenden Frames
         int currentRow,                                                         // Reihe des zu Rendernden Frames in Source-Grafik-Datei -->  Unterschied zum feststehenden Frame
        int currentFrame,                                                     // Spalte (das wievielte Frame  in der Reihe) des zu Rendernden Frames in Source-Grafik-Datei -->  Unterschied zum feststehenden Frame
        SDL_Renderer *pRenderer, 
        SDL_RendererFlip flip)
    {
        SDL_Rect srcRect;                    // Quell-Viereck wird erstellt
        SDL_Rect destRect;                    // Ziel-Viereck wird erstellt
         srcRect.x = width * currentFrame;                                     // x-Position des oberen linken Ecks des Quellrechtecks -->  Unterschied zum feststehenden Frame
        srcRect.y = height *  (currentRow - 1);                                // y-Position des  oberen linken Ecks des Quellrechtecks --> Unterschied zum  feststehenden Frame
        srcRect.w = destRect.w = width;        // Breite des Quell- und Ziel-Rechtecks
        srcRect.h = destRect.h = height;    // Höhe des Quell- und Ziel-Rechtecks
        destRect.x = x;                        // x-Position des oberen linken Ecks des Zielrechtecks auf dem virtuellen Bildschirm
        destRect.y = y;                        // x-Position des oberen linken Ecks des Zielrechtecks auf dem virtuellen Bildschirm
        SDL_RenderCopyEx(                    // Zu verwendender Renderer
            pRenderer,
            m_textureMap[id],                // ID des Grafikobjekts
            &srcRect,                        // Zeiger auf Quell-Rechteck
            &destRect,                        // Zeiger auf Ziel-Rechteck
            0,
            0,
            flip);
    }
    Enemy.h
    Code:
    //  Enemy.h
    // abgeleitet (derived) von GameObject
    #include <iostream>        // im Buch nicht erwähnt, aber nötig wegen cout
    #include "GameObject.h" // im Buch nicht erwähnt aber notwendig, da sonst nicht von GameObject geerbt werden kann
    #ifndef __Enemy__
    #define __Enemy__
    
    class Enemy : public GameObject // inherit from GameObject
    {
    public:
    
        Enemy(){}
        ~Enemy(){}
    
        void load(int x, int y, int width, int height, std::string
            textureID);
    
        void draw(SDL_Renderer* pRenderer);
        void update();
        void clean();
    Enemy.cpp
    Code:
    #include "Enemy.h"
    
    // Wird erst auf Seite 59 eingefügt
    void Enemy::load(
        int x,
        int y,
        int width,
        int height,
        std::string textureID)    // Fehler im Buch (vor dem string fehlt 'std::'
    {
        GameObject::load(x, y, width, height, textureID);
    }
    
    void Enemy::draw(SDL_Renderer* pRenderer)
    {
        GameObject::draw(pRenderer);
    
    }
    
    void Enemy::update()
    {
        m_y += 1;
        m_x += 1;
        m_currentFrame = int(((SDL_GetTicks() / 100) % 6)); 
    }
    Player.h
    Code:
    //  Player.h
    // abgeleitet (derived) von GameObject
    #include <iostream>        // im Buch nicht erwähnt, aber nötig wegen cout
    #include "GameObject.h" // im Buch nicht erwähnt aber notwendig, da sonst nicht von GameObject geerbt werden kann
    #ifndef __Player__
    #define __Player__
    
    class Player : public GameObject // inherit from GameObject
    {
    public:
    
        Player(){}
        ~Player(){}
    
        void load(int x, int y, int width, int height, std::string
            textureID);
    
        void draw(SDL_Renderer* pRenderer);
        void update();
        void clean();
    
    
    };
    #endif /* defined(Player) */
    Player.cpp
    Code:
    #include "Player.h"
    
    void Player::load(
        int x, 
        int y, 
        int width, 
        int height, 
        std::string textureID)    // Fehler im Buch (vor dem string fehlt 'std::'
    {
        GameObject::load(x, y, width, height, textureID);
    }
    
    void Player::draw(SDL_Renderer* pRenderer)
    {
        GameObject::draw(pRenderer);
        
    }
    
    void Player::update()
    {
        m_x += 2;
        m_currentFrame = int(((SDL_GetTicks() / 100) % 6)); // --> wurde im Buch auf Seite 53 vergessen. 
                                                            // Wird dies nicht eingefügt, gibt es keine 
                                                            // Animation von "Player m_player", welches
                                                            // in Game.h ein Klassenmember ist. Im 
                                                            // Gegensatz wird die Animation von
                                                            // "GameObject m_go" in GameObject::Update
                                                            // realisiert. Leider wurde dies im Buch
                                                            // völlig vergessen, so dass keine 
                                                            // Animation zu sehen war.
    }
    a lot of Code.. I know :-).. Just if you want to copy and paste, to try and verify, with what I was doing.. following I will Post my Damn-Mistake-Version of implementing chapter three.. But don´t laugh.. You will find a lot of mistakes I made, for sure.. Just If you want to try.. I would understand, if you have better things to do as correcting so many mistakes :-)

    Best Regards

    Sonntag69

Popular pages Recent additions subscribe to a feed

Similar Threads

  1. My ini load code.
    By RMDan in forum C Programming
    Replies: 16
    Last Post: 06-25-2009, 12:07 AM
  2. load image from scanner
    By Colin in forum C++ Programming
    Replies: 2
    Last Post: 01-20-2003, 01:53 PM
  3. How to write a C code to load an image file.
    By dv007 in forum C Programming
    Replies: 4
    Last Post: 05-25-2002, 05:27 PM
  4. How-To: Load Pictures in MFC. Code Inside.
    By Xei in forum C++ Programming
    Replies: 1
    Last Post: 05-16-2002, 09:17 PM
  5. Load and run machine code at runtime
    By ninebit in forum C++ Programming
    Replies: 8
    Last Post: 02-27-2002, 10:26 AM