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

  1. #16
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Ugh, it's been a while since I've done any file-sharing, and it's become more complicated than it used to be. I'm just going to post the pertinent stuff here, let me know if I miss a file you might need.

    ---LoaderParams.h---
    Code:
    #ifndef LOADERPARAMS_H_INCLUDED
    #define LOADERPARAMS_H_INCLUDED
    
    #include <string>
    
    class LoaderParams
    {
    public:
        LoaderParams(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)
        {
        }
    
        int getX()const{ return m_x; }
    
        int getY()const{ return m_y; }
    
        int getWidth()const{ return m_width; }
    
        int getHeight()const{ return m_height; }
    
        std::string getTextureID()const{ return m_textureID; }
    
    private:
    
        int m_x;
        int m_y;
        int m_width;
        int m_height;
        std::string m_textureID;
    };///:::--End LoaderParams--:::///
    #endif // LOADERPARAMS_H_INCLUDED
    ---GameObject.h---
    Code:
    #ifndef GAMEOBJECT_H_INCLUDED
    #define GAMEOBJECT_H_INCLUDED
    
    class LoaderParams;
    
    class GameObject
    {
    public:
        virtual ~GameObject(){}
        virtual void draw()=0;
        virtual void update()=0;
        virtual void clean()=0;
    
    protected:
        GameObject(const LoaderParams* pParams){}
    
    private:
        GameObject(const GameObject&);
        GameObject& operator=(const GameObject&);
    };
    
    #endif // GAMEOBJECT_H_INCLUDED

    ---Game.h---
    Code:
    #ifndef GAME_H_INCLUDED
    #define GAME_H_INCLUDED
    
    #include <vector>
    #include <SDL.h>
    
    class GameObject;
    
    ///::::--class Game--::::///
    class Game
    {
    private:
        Game (const Game&);
        Game&operator=(const Game&);
        Game():
            m_currentFrame(0),
             m_bRunning{false},
             m_pWindow(0),
             m_pRender(0),
            m_gameObjects()
        {
        }
    
    public:
        ///Game as a singleton:
        static Game* Instance()
        {
            if(!s_pInstance)
            {
                s_pInstance = new Game();
                return s_pInstance;
            }
            return s_pInstance;
        }
        ~Game(){}
    
        /// simply set the running variable to true
        bool init(const char* title,int xpos, int ypos, int width, int height, bool fullscreen);
    
        void render();
        void update();
        void handleEvents();
        void clean();
        void quit(){ SDL_Quit(); }
    
        /// Accessors
        bool running() { return m_bRunning; }
        SDL_Renderer* getRender() const { return m_pRender; }
    
    private:
    
        static Game* s_pInstance;
        int m_currentFrame;
        bool m_bRunning;
        SDL_Window* m_pWindow;
        SDL_Renderer* m_pRender;
        std::vector<GameObject*> m_gameObjects;
    
    }; ///:::-End Game-:::///
    
    typedef Game TheGame;
    
    #endif // GAME_H_INCLUDED

    ---game.cpp---
    Code:
    #include "game.h"
    #include <iostream>
    #include "texturemanager.h"
    #include "enemy.h"
    #include "player.h"
    #include "loaderparams.h"
    #include "inputhandler.h"
    
    ///static instance singleton definition:
    Game* Game::s_pInstance = 0;
    
    bool Game::init(const char* title, int xpos, int ypos, int width, int height, bool fullscreen)
    {
        int flags = 0;
        if(fullscreen == true){flags = SDL_WINDOW_FULLSCREEN;}
        /// attempt to initialize SDL
        if(SDL_Init(SDL_INIT_EVERYTHING) == 0)
        {
            std::cout << "SDL init success\n";
            /// init the window
            m_pWindow = SDL_CreateWindow(title, xpos, ypos, width, height, flags);
            if(m_pWindow)
            {
                /// window init success
                std::cout << "window creation success\n";
                m_pRender = SDL_CreateRenderer(m_pWindow, -1, 0);
                if(m_pRender)
                {
                    /// renderer init success
                    std::cout << "renderer creation success\n";
                    SDL_SetRenderDrawColor(m_pRender, 255,255,255,255);
                }
                else
                {
                    std::cout << "renderer init fail\n";
                    return false; // renderer init fail
                }
            }
            else
            {
                std::cout << "window init fail\n";
                return false; // window init fail
            }
        }
        else
        {
            std::cout << "SDL init fail\n";
            return false; // SDL init fail
        }
        ///load into texture map:
        if(!TextManage::Instance()->load("C:/Directory/image.png", "dragon", m_pRender))
        {
            return false;
        }
        if(!TextManage::Instance()->load("C:/Directory.image.png", "fireball", m_pRender))
        {
            return false;
        }
        ///create new GameObjects types:
        m_gameObjects.push_back(new Enemy(new LoaderParams(0, 0, 93, 124, "dragon")));
        m_gameObjects.push_back(new Enemy(new LoaderParams(300, 300, 64, 64, "fireball")));
        std::cout << "init success\n";
        m_bRunning = true;
        /// everything inited successfully, start the main loop
        return true;
    }
    
    void Game::update()
    {
        ///loop through GameObject* vector, update using polymorphism:
        for(std::vector<GameObject*>::size_type i = 0; i != m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->update();
        }
        ///update Game::currentFrame:
        m_currentFrame = int(((SDL_GetTicks() / 70) % 4));
    }
    
    void Game::render()
    {
        ///clear the renderer:
        SDL_RenderClear(m_pRender);
        ///Draw from GameObject vector using polymorphism:
        for(std::vector<GameObject*>::size_type i = 0; i != m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->draw();
        }
        ///Present the new Rendering
        SDL_RenderPresent(m_pRender);
    }
    void Game::clean()
    {
        std::cout << "cleaning game\n";
        SDL_DestroyWindow(m_pWindow);
        SDL_DestroyRenderer(m_pRender);
        TheInputHandler::Instance()->clean();
        SDL_Quit();
    }
    void Game::handleEvents()
    {
        TheInputHandler::Instance()->update();
    }
    ---sdlgameobject.h---
    Code:
    #ifndef SDLGAMEOBJECT_H_INCLUDED
    #define SDLGAMEOBJECT_H_INCLUDED
    
    #include <string>
    #include "gameobject.h"
    #include "vector2d.h"
    
    class SDLGameObject : public GameObject
    {
    public:
        SDLGameObject(const LoaderParams* pParams);
        virtual void draw();
        virtual void update();
        virtual void clean();
        virtual ~SDLGameObject(){}
    
    protected:
        int m_width;
        int m_height;
        int m_currentRow;
        int m_currentFrame;
        std::string m_textureID;
        Vector2D m_position;
        Vector2D m_velocity;
        Vector2D m_acceleration;
    };
    
    #endif // SDLGAMEOBJECT_H_INCLUDED

    ---sdlgameobject.cpp---
    Code:
    #include "sdlgameobject.h"
    #include "loaderparams.h"
    #include "texturemanager.h"
    #include "game.h"
    #include "inputhandler.h"
    
    SDLGameObject::SDLGameObject(const LoaderParams* pParams):
        GameObject(pParams),
        m_width(pParams->getWidth()),
        m_height(pParams->getHeight()),
        m_currentRow(1),
        m_currentFrame(1),
        m_textureID(pParams->getTextureID()),
        m_position(pParams->getX(), pParams->getY()),
        m_velocity(0, 0),
        m_acceleration(0, 0)
    {
    }
    
    void SDLGameObject::draw()
    {
    
        TextManage::Instance()->drawFrame(m_textureID,
                                          (int)m_position.getX(),
                                          (int)m_position.getY(),
                                          m_width,
                                          m_height,
                                          m_currentRow,
                                          m_currentFrame,
                                          TheGame::Instance()->getRender(),
                                          flip);
    }
    
    void SDLGameObject::update()
    {
        m_velocity += m_acceleration;
        m_position += m_velocity;
    }
    
    void SDLGameObject::clean()
    {
    }

    ---player.h---
    Code:
    #ifndef PLAYER_H_INCLUDED
    #define PLAYER_H_INCLUDED
    
    #include "sdlgameobject.h"
    
    class Player: public SDLGameObject
    {
    public:
        virtual ~Player(){}
        Player(const LoaderParams* pParams);
        void handleInput();
        virtual void draw();
        virtual void update();
        virtual void clean();
    };
    
    #endif // PLAYER_H_INCLUDED
    ---player.cpp---

    Code:
    #include "player.h"
    #include "inputhandler.h"
    
    /// SDLGameObject contains all necessary variables for player
    Player::Player(const LoaderParams* pParams): SDLGameObject(pParams){}
    
    void Player::draw()
    {
        SDLGameObject::draw();
    }
    void Player::handleInput()
    {
        /// I've erased stuff here because it was specific to the sprites I was using at the time.
        
        /// This is where you write the player control logic using InputHandler
    }
    
    void Player::update()
    {
        handleInput();
        m_currentFrame = int (((SDL_GetTicks() / 100) % 3));
        SDLGameObject::update();
    }
    void Player::clean()
    {
    }

    ---enemy.h---
    Code:
    #ifndef ENEMY_H_INCLUDED
    #define ENEMY_H_INCLUDED
    
    #include "sdlgameobject.h"
    
    class Enemy : public SDLGameObject
    {
    public:
        Enemy(const LoaderParams* pParams);
        virtual void draw();
        virtual void update();
        virtual void clean();
    };
    
    #endif // ENEMY_H_INCLUDED

    ---enemy.cpp---
    Code:
    #include "enemy.h"
    #include "game.h"
    #include "inputhandler.h"
    
    /// SDLGameObject contains all variables needed for Enemy
    Enemy::Enemy(const LoaderParams* pParams): SDLGameObject(pParams){}
    
    void Enemy::draw()
    {
        /// Handle enemy drawing generically
        SDLGameObject::draw();
    }
    
    void Enemy::update()
    {
        /// Update Frame:
        m_currentFrame = int(((SDL_GetTicks() / 100) % 3));
        
        /// Update position generically 
        SDLGameObject::update();
    }
    void Enemy::clean()
    {
    }

    I think that's all the necessary files from that chapter. Some of the rest are quite large, let me know if you want a specific file and I'll post it, but this should be everything that was changed during that chapter.

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

    Thumbs down The Bad - headache-making Code....

    And now the not-any-more-working-Code after making abstract and putting together.. till Side 67 :-)

    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)
    
    
    // --> Seite 64 Die komplette main wird ersetzt
    int main(int argc, char* argv[])
    {
        std::cout << "game init attempt...\n";
        if (TheGame::Instance()->init("Chapter 1", 100, 100, 640, 480,
            false))
        {
            std::cout << "game init success!\n";
            while (TheGame::Instance()->running())
            {
                TheGame::Instance()->handleEvents();
                TheGame::Instance()->update();
                TheGame::Instance()->render();
                SDL_Delay(10);
            }
        }
        else
        {
            std::cout << "game init failure - " << SDL_GetError() << "\n";
            return -1;
        }
        std::cout << "game closing...\n";
        TheGame::Instance()->clean();
        return 0;
    }
    Game.h
    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)
    
    
    // --> Seite 64 Die komplette main wird ersetzt
    int main(int argc, char* argv[])
    {
        std::cout << "game init attempt...\n";
        if (TheGame::Instance()->init("Chapter 1", 100, 100, 640, 480,
            false))
        {
            std::cout << "game init success!\n";
            while (TheGame::Instance()->running())
            {
                TheGame::Instance()->handleEvents();
                TheGame::Instance()->update();
                TheGame::Instance()->render();
                SDL_Delay(10);
            }
        }
        else
        {
            std::cout << "game init failure - " << SDL_GetError() << "\n";
            return -1;
        }
        std::cout << "game closing...\n";
        TheGame::Instance()->clean();
        return 0;
    }
    Game.cpp
    Code:
    #include "Game.h"
    #include <iostream>
    
    
    using namespace std;
    
    Game* Game::s_pInstance = 0; // --> Seite 64 (Es wird ein Zeiger auf die  Singletoninstanz von Game initialisiert)
    
    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_gameObjects.push_back(new Player(new LoaderParams(100, 100, 128, 82, "animate")));
        m_gameObjects.push_back(new Enemy(new LoaderParams(300, 300, 128, 82, "animate")));
    
    
        // 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(); //SDL-Renderer-Parameter wurde auf Seite 63 herausgenommen
        }
    }
    
    
    
    void Game::update()
    {
        // loop durch die Objekte und diese malen
        for (std::vector<GameObject*>::size_type i = 0; i !=
            m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->update();
        }
    
    
        m_currentFrame = int(((SDL_GetTicks() / 100) % 6)); // --> Seite 45
        // m_go.update();        --> wurde rausgenommen beim Kapitel Polymorphism(wurde allerdings auch wieder nicht im Buch erwähnt
        // m_player.update();    --> kann aufgrund des gleichen Namens wie des eingeführten Zeigers auf Seite 56 so nicht mehr verwendet werden
        
        
        
    }
    
    
    
    void Game::render()
    {
    
        SDL_RenderClear(m_pRenderer); // lösche zur Hintergrundfarbe
    
        // m_go.draw(m_pRenderer);            // --> Seite 54 --> wurde rausgenommen beim Kapitel Polymorphism (wurde allerdings auch wieder nicht im Buch erwähnt
        // m_player.draw(m_pRenderer);        // --> Seite 54 --> kann aufgrund des gleichen Namens wie des eingeführten Zeigers auf Seite 56 so nicht mehr verwendet werden
        
        // loop durch die Objekte und diese malen
        for (std::vector<GameObject*>::size_type i = 0; i !=
            m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->draw(); // wird auf Seite 63 entfernt
        }
        
        SDL_RenderPresent(m_pRenderer);
    }
    
    // Dieser Handler ist im moment nur dazu da, damit man aus dem Programm aussteigen kann.
    // Wenn man auf das X oben rechts im Fenster drückt.
    void Game::handleEvents()
    {
        SDL_Event event;
        if (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_QUIT:
                m_bRunning = false;
                break;
            default:
                break;
            }
        }
    }
    
    // Diese Funktion räumt unser Programm auf und schließt alle SDL-Initialisierungen.
    void Game::clean()
    {    
        IMG_Quit();
        SDL_DestroyWindow(m_pWindow);
        SDL_DestroyRenderer(m_pRenderer);
        SDL_Quit();
    }
    GameObject.h
    Code:
    #include "Game.h"
    #include <iostream>
    
    
    using namespace std;
    
    Game* Game::s_pInstance = 0; // --> Seite 64 (Es wird ein Zeiger auf die  Singletoninstanz von Game initialisiert)
    
    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_gameObjects.push_back(new Player(new LoaderParams(100, 100, 128, 82, "animate")));
        m_gameObjects.push_back(new Enemy(new LoaderParams(300, 300, 128, 82, "animate")));
    
    
        // 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(); //SDL-Renderer-Parameter wurde auf Seite 63 herausgenommen
        }
    }
    
    
    
    void Game::update()
    {
        // loop durch die Objekte und diese malen
        for (std::vector<GameObject*>::size_type i = 0; i !=
            m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->update();
        }
    
    
        m_currentFrame = int(((SDL_GetTicks() / 100) % 6)); // --> Seite 45
        // m_go.update();        --> wurde rausgenommen beim Kapitel Polymorphism(wurde allerdings auch wieder nicht im Buch erwähnt
        // m_player.update();    --> kann aufgrund des gleichen Namens wie des eingeführten Zeigers auf Seite 56 so nicht mehr verwendet werden
        
        
        
    }
    
    
    
    void Game::render()
    {
    
        SDL_RenderClear(m_pRenderer); // lösche zur Hintergrundfarbe
    
        // m_go.draw(m_pRenderer);            // --> Seite 54 --> wurde rausgenommen beim Kapitel Polymorphism (wurde allerdings auch wieder nicht im Buch erwähnt
        // m_player.draw(m_pRenderer);        // --> Seite 54 --> kann aufgrund des gleichen Namens wie des eingeführten Zeigers auf Seite 56 so nicht mehr verwendet werden
        
        // loop durch die Objekte und diese malen
        for (std::vector<GameObject*>::size_type i = 0; i !=
            m_gameObjects.size(); i++)
        {
            m_gameObjects[i]->draw(); // wird auf Seite 63 entfernt
        }
        
        SDL_RenderPresent(m_pRenderer);
    }
    
    // Dieser Handler ist im moment nur dazu da, damit man aus dem Programm aussteigen kann.
    // Wenn man auf das X oben rechts im Fenster drückt.
    void Game::handleEvents()
    {
        SDL_Event event;
        if (SDL_PollEvent(&event))
        {
            switch (event.type)
            {
            case SDL_QUIT:
                m_bRunning = false;
                break;
            default:
                break;
            }
        }
    }
    
    // Diese Funktion räumt unser Programm auf und schließt alle SDL-Initialisierungen.
    void Game::clean()
    {    
        IMG_Quit();
        SDL_DestroyWindow(m_pWindow);
        SDL_DestroyRenderer(m_pRenderer);
        SDL_Quit();
    }
    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.
    //}
    //
    SDLGameObject.h
    Code:
    //SDLGameObject.h --> wird auf Seite 65 erzeugt
    // erbt von GameObject
    #include "GameObject.h" // --> im Buch nicht erwähnt
    #include "LoaderParams.h" // --> im Buch nicht erwähnt
    
    class SDLGameObject : public GameObject
    {
    public:
        SDLGameObject(){}
        SDLGameObject(const LoaderParams* pParams);
        virtual void draw();
        virtual void update();
        virtual void clean();
    
    
    
    
    
    
    
    
    protected:
        int m_x;
        int m_y;
        int m_width;
        int m_height;
        int m_currentRow;
        int m_currentFrame;
        std::string m_textureID;
    };
    SDLGameObject.cpp
    Code:
    #include "SDLGameObject.h"
    #include "LoaderParams.h"
    #include "Game.h"
    
    SDLGameObject::SDLGameObject(const LoaderParams* pParams) :
    GameObject(pParams)
    {
    
        m_x = pParams->getX();
        m_y = pParams->getY();
        m_width = pParams->getWidth();
        m_height = pParams->getHeight();
        m_textureID = pParams->getTextureID();
        m_currentRow = 1;
        m_currentFrame = 1;
    }
    
    void SDLGameObject::draw()
    {
        TextureManager::Instance()->drawFrame(m_textureID, m_x, m_y,
            m_width, m_height, m_currentRow, m_currentFrame,
            TheGame::Instance()->getRenderer());
    }
    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);
    }
    Player.h
    Code:
    #ifndef __Player__
    #define __Player__
    //  Player.h
    // abgeleitet (derived) von GameObject
    #include <iostream>        // im Buch nicht erwähnt, aber nötig wegen cout
    #include "SDLGameObject.h" // im Buch nicht erwähnt aber notwendig, da sonst nicht von GameObject geerbt werden kann
    
    
    class Player : public SDLGameObject // inherit from GameObject
    {
    public:
    
        Player(){}
        ~Player(){}
    
        Player(const LoaderParams* pParams);        // --> Seite 66
    
        void load(int x, int y, int width, int height, std::string
            textureID);
    
        virtual void draw();        // --> Seite 66
        virtual void update();        // --> Seite 66
        virtual void clean();        // --> Seite 66
    
    
    };
    #endif /* defined(Player) */
    Player.cpp
    Code:
    #include "Player.h"
    
    
    // --> Wird auf Seite 66/67 komplett ersetzt
    Player::Player(const LoaderParams* pParams) :
    SDLGameObject(pParams)
    {
    }
    void Player::draw()
    {
        SDLGameObject::draw(); // nun wird das SDL GameObject genutzt
    }
    void Player::update()
    {
        m_x -= 1;
        m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
    }
    void Player::clean()
    {
    }
    Enemy.h
    Code:
    #ifndef __Enemy__
    #define __Enemy__
    //  Enemy.h
    // abgeleitet (derived) von GameObject
    #include <iostream>        // im Buch nicht erwähnt, aber nötig wegen cout
    #include "SDLGameObject.h" // im Buch nicht erwähnt aber notwendig, da sonst nicht von GameObject geerbt werden kann
    
    
    class Enemy : public SDLGameObject // inherit from GameObject
    {
    public:
    
        Enemy(){}
        ~Enemy(){}
    
        Enemy(const LoaderParams* pParams);    // --> Seite 66
    
        void load(int x, int y, int width, int height, std::string
            textureID);
    
    
    
    
        virtual void draw();        // --> Seite 66
        virtual void update();        // --> Seite 66
        virtual void clean();        // --> Seite 66
    
    
    };
    #endif /* defined(__Enemy__) */
    Enemy.cpp
    Code:
    #include "Enemy.h"
    
    
    // --> Wird auf Seite 66/67 komplett ersetzt
    Enemy::Enemy(const LoaderParams* pParams) :
    SDLGameObject(pParams)
    {
    }
    void Enemy::draw()
    {
        SDLGameObject::draw(); // nun wird das SDL GameObject genutzt
    }
    void Enemy::update()
    {
        m_x -= 1;
        m_currentFrame = int(((SDL_GetTicks() / 100) % 6));
    }
    void Enemy::clean()
    {
    }
    LoaderParams.h
    Code:
    #ifndef __LoaderParams__
    #define __LoaderParams__
    
    //LoaderParamsd.h
    #include <iostream>
    
    using namespace std;
    
    class LoaderParams
    {
    public:
        // LoaderParams(){}
        ~LoaderParams(){}
    
        // Konstruktor
        LoaderParams(int x, int y, int width, int height, std::string textureID) :
    
            // Werte die an den Konstruktor übergeben werden da von doppelpunkt gefolgt. s.o.
            m_x(x), m_y(y), m_width(width), m_height(height), m_textureID(textureID)
        {
        }
    
    
        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;
        std::string m_textureID;
    
    };
    #endif
    So.. Thats all.. And I´m really confused about my own Code *lol.. like I said.. I am a newbee and so please forgive me stupid mistakes you will find :-)..

    Best Regards

    Thomas Klaes

  3. #18
    Registered User
    Join Date
    Sep 2014
    Posts
    13
    Quote Originally Posted by Alpo View Post
    Ugh, it's been a while since I've done any file-sharing, and it's become more complicated than it used to be. I'm just going to post the pertinent stuff here, let me know if I miss a file you might need.

    I think that's all the necessary files from that chapter. Some of the rest are quite large, let me know if you want a specific file and I'll post it, but this should be everything that was changed during that chapter.
    Woaahh.. thats really fast :-).. Thank You a lot :-).. I saw that you implemented the eventhandler already :-).. could you send that code, too :-).. and your main.cpp... only to get sure, It will work together :-)

    Best Regards

    Thomas Klaes

  4. #19
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Sonntag69 View Post
    Woaahh.. thats really fast :-).. Thank You a lot :-).. I saw that you implemented the eventhandler already :-).. could you send that code, too :-).. and your main.cpp... only to get sure, It will work together :-)

    Best Regards

    Thomas Klaes
    I think we just happened to post on top of each other lol. Sure I can do that, the inputhandler might be a bit messy though. It's one of the largest files (and it really gets huge in my latest iterations).

    Its a singleton with a typedef (supposedly for convenience, although the typedef actually uses more typing), you can access it through doing

    Code:
       TheInputHandler->Instance()->Function( Parameters ); 
       /// Or whatever the form of the specific function is.
    Make sure you test the JoyStick functions before depending on them. I couldn't get ahold of a controller to test them out with, so there might be an error in some piece of JoyStick code.


    ---InputHandler.h---
    Code:
    #ifndef INPUTHANDLER_H_INCLUDED
    #define INPUTHANDLER_H_INCLUDED
    
    #include <SDL.h>
    #include <vector>
    #include "vector2d.h"
    
    /// enum of mouse buttons for use in other files
    enum mouse_buttons{LEFT, MIDDLE, RIGHT};
    
    class InputHandler
    {
    
    public:
    
        static InputHandler* Instance()
        {
            if(!s_pInstance){
                s_pInstance = new InputHandler();
            }
            return s_pInstance;
        }
    
        /// --------- Joystick Functions ---------- ///
    
        /// Initialize as many as detected, put in vector
        void initializeJoysticks();
    
        /// Determine if joystick initialized
        bool joystickInitialized(){ return m_bJoysticksInitialized; }
    
        /// Get values on analogue sticks for each controller
        /// joy = controller number, stick = which analogue stick
        int xvalue(int joy, int stick);
        int yvalue(int joy, int stick);
    
        /// Test button states, joy = controller id:
        bool getButtonState(int joy, int buttonNumber)
        {
            return m_buttonStates[joy][buttonNumber];
        }
    
        ///----------Mouse Functions----------///
    
        /// access button states
        bool getMouseButtonState(int buttonNumber)
        {
            return m_mouseButtonStates[buttonNumber];
        }
    
        ///access mouse position
        Vector2D getMousePosition(){ return m_mousePosition; }
    
        ///----------Keyboard Functions----------///
    
        /// get state of keys
        bool isKeyDown(SDL_Scancode key);
    
        /// update InputHandler by polling for events:
        void update();
    
        /// clear devices we have initialized:
        void clean();
    
    private:
    
        ///--------- Utility ---------///
        InputHandler():
            m_bJoysticksInitialized(false),
            m_joysticks(0),
            m_joystickValues(0),
            m_buttonStates(0),
            m_mouseButtonStates(0),
            m_mousePosition(),
            m_keystates(0)
        {
            for(int i = 0; i < mousebuttons; i++){
                m_mouseButtonStates.push_back(false);
            }
        }
    
        ~InputHandler(){}
    
        static InputHandler* s_pInstance;
    
        /// Prevent copy ctor or assignment:
        InputHandler(const InputHandler&);
        InputHandler& operator=(const InputHandler&);
    
        /// --------Joystick variables--------- ///
    
        /// Initialized?
        bool m_bJoysticksInitialized;
    
        /// dead input area (mid stick)
        static const int m_joystickDeadZone = 10000;
    
        /// Container for multiple controllers:
        std::vector<SDL_Joystick*> m_joysticks;
    
        /// Vector pair represents analogue sticks for each controller:
        std::vector<std::pair<Vector2D*, Vector2D*> > m_joystickValues;
    
        /// Container to hold button values:
        std::vector<std::vector<bool> > m_buttonStates;
    
        /// ---------Mouse Variables----------- ///
    
        /// bool vector for mouse button state:
        std::vector<bool> m_mouseButtonStates;
    
        /// max number mouse buttons:
        static const int mousebuttons = 3;
    
        /// Vector2d for motion information:
        Vector2D m_mousePosition;
    
        /// ---------Keyboard Variable------- ///
    
        const Uint8* m_keystates;
    
        /// ---------Event loop Functions-------- ///
    
        /// keyboard :
        void onKeyDown();
        void onKeyUp();
    
        /// mouse :
        void onMouseMove(SDL_Event& event);
        void onMouseButtonDown(SDL_Event& event);
        void onMouseButtonUp(SDL_Event& event);
    
        /// controller :
        void onJoystickAxisMove(SDL_Event& event);
        void onJoystickButtonDown(SDL_Event& event);
        void onJoystickButtonUp(SDL_Event& event);
    };
    
    typedef InputHandler TheInputHandler;
    
    #endif // INPUTHANDLER_H_INCLUDED
    ---InputHandler.cpp---
    Code:
    #include "inputhandler.h"
    #include "game.h"
    #include <SDL.h>
    #include <iostream>
    
    InputHandler* InputHandler::s_pInstance = 0;
    
    /// --------- Controller --------- ///
    
    void InputHandler::initializeJoysticks()
    {
        if(!SDL_WasInit(SDL_INIT_JOYSTICK))
        {
            SDL_InitSubSystem(SDL_INIT_JOYSTICK);
        }
        if(SDL_NumJoysticks() > 0)
        {
            for(int i = 0; i < SDL_NumJoysticks(); i++)
            {
                SDL_Joystick* joy = SDL_JoystickOpen(i);
                if(joy)
                {
                    m_joysticks.push_back(joy);
                    m_joystickValues.push_back(std::make_pair( new Vector2D(0, 0), new Vector2D(0, 0)));
                    std::vector<bool> tempButtons;
                    for(int j = 0; j < SDL_JoystickNumButtons(joy); j++)
                    {
                        tempButtons.push_back(false);
                    }
                    m_buttonStates.push_back(tempButtons);
                }
                else
                {
                    std::cout << "InputHandler::InitializedJoysticks() - Error : " << SDL_GetError() << "\n";
                }
            }
            SDL_JoystickEventState(SDL_ENABLE);
            m_bJoysticksInitialized = true;
            std::cout << m_joysticks.size() << " Joysticks Initialized\n";
        }
        else
        {
            m_bJoysticksInitialized = false;
            std::cout << "No Joysticks found\n";
        }
    }
    
    int InputHandler::xvalue(int joy, int stick)
    {
        if(m_joystickValues.size() > 0)
        {
            if(stick == 1)
            {
                return m_joystickValues[joy].first->getX();
            }
            else if(stick == 2)
            {
                return m_joystickValues[joy].second->getX();
            }
        }
    
        return 0;
    }
    
    int InputHandler::yvalue(int joy, int stick)
    {
        if(m_joystickValues.size() > 0)
        {
            if(stick == 1)
            {
                return m_joystickValues[joy].first->getY();
            }
            else if(stick == 2)
            {
                return m_joystickValues[joy].second->getY();
            }
        }
    
        return 0;
    }
    
    
    /// ------- Get Keyboard Button State ------- ///
    bool InputHandler::isKeyDown(SDL_Scancode key)
    {
        if(m_keystates)
        {
            if(m_keystates[key] == 1)
                return true;
            else return false;
        }
    
        return false;
    }
    
    
    /// ------- Input Update Loop ------- ///
    void InputHandler::update()
    {
        SDL_Event event;
    
        while(SDL_PollEvent(&event))
        {
            m_keystates = SDL_GetKeyboardState(0);
    
            switch(event.type)
            {
                case SDL_QUIT:
                    TheGame::Instance()->clean(); break;
    
                case SDL_JOYAXISMOTION:
                    onJoystickAxisMove(event); break;
    
                case SDL_JOYBUTTONDOWN:
                    onJoystickButtonDown(event); break;
    
                case SDL_JOYBUTTONUP:
                    onJoystickButtonUp(event); break;
    
                case SDL_MOUSEMOTION:
                    onMouseMove(event); break;
    
                case SDL_MOUSEBUTTONDOWN:
                    onMouseButtonDown(event); break;
    
                case SDL_MOUSEBUTTONUP:
                    onMouseButtonUp(event); break;
    
                case SDL_KEYDOWN:
                    onKeyDown(); break;
    
                case SDL_KEYUP:
                    onKeyUp(); break;
    
                default: break;
            }
        }
    
    }
    void InputHandler::onKeyDown()
    {
    }
    
    void InputHandler::onKeyUp()
    {
    }
    
    inline void InputHandler::onMouseMove(SDL_Event& event)
    {
        m_mousePosition.setX(event.motion.x);
        m_mousePosition.setY(event.motion.y);
    }
    
    inline void InputHandler::onMouseButtonDown(SDL_Event& event)
    {
        if(event.button.button == SDL_BUTTON_LEFT)
        {
            m_mouseButtonStates[LEFT] = true;
        }
        if(event.button.button == SDL_BUTTON_MIDDLE)
        {
            m_mouseButtonStates[MIDDLE] = true;
        }
        if(event.button.button == SDL_BUTTON_RIGHT)
        {
            m_mouseButtonStates[RIGHT] = true;
        }
    }
    
    inline void InputHandler::onMouseButtonUp(SDL_Event& event)
    {
        if(event.button.button == SDL_BUTTON_LEFT)
        {
            m_mouseButtonStates[LEFT] = false;
        }
        if(event.button.button == SDL_BUTTON_MIDDLE)
        {
            m_mouseButtonStates[MIDDLE] = false;
        }
        if(event.button.button == SDL_BUTTON_RIGHT)
        {
            m_mouseButtonStates[RIGHT] = false;
        }
    }
    
    inline void InputHandler::onJoystickAxisMove(SDL_Event& event)
    {
        int whichOne = event.jaxis.which;
    
        ///Left stick horizontal:
        if(event.jaxis.axis == 0)
        {
            if(event.jaxis.value > m_joystickDeadZone)
            {
                m_joystickValues[whichOne].first->setX(1);
            }
            else if(event.jaxis.value < -m_joystickDeadZone)
            {
                m_joystickValues[whichOne].first->setX(-1);
            }
            else
            {
                m_joystickValues[whichOne].first->setX(0);
            }
        }
    
        ///left stick vertical:
        if(event.jaxis.axis == 1)
        {
            if(event.jaxis.value > m_joystickDeadZone)
            {
                m_joystickValues[whichOne].first->setY(1);
            }
            else if(event.jaxis.value < -m_joystickDeadZone)
            {
                m_joystickValues[whichOne].first->setY(-1);
            }
            else
            {
                m_joystickValues[whichOne].first->setY(0);
            }
        }
    
        ///right stick horizontal:
        if(event.jaxis.axis == 3)
        {
            if(event.jaxis.value > m_joystickDeadZone)
            {
                m_joystickValues[whichOne].second->setX(1);
            }
            else if(event.jaxis.value < -m_joystickDeadZone)
            {
                m_joystickValues[whichOne].second->setX(-1);
            }
            else
            {
                m_joystickValues[whichOne].second->setX(0);
            }
        }
    
        ///right stick vertical:
        if(event.jaxis.axis == 4)
        {
            if(event.jaxis.value > m_joystickDeadZone)
            {
                m_joystickValues[whichOne].second->setY(1);
            }
            else if(event.jaxis.value < -m_joystickDeadZone)
            {
                m_joystickValues[whichOne].second->setY(-1);
            }
            else
            {
                m_joystickValues[whichOne].second->setY(0);
            }
        }
    }
    
    inline void InputHandler::onJoystickButtonDown(SDL_Event& event)
    {
        int whichOne = event.jaxis.which;
        m_buttonStates[whichOne][event.jbutton.button] = false;
    }
    
    inline void InputHandler::onJoystickButtonUp(SDL_Event& event)
    {
        int whichOne = event.jaxis.which;
        m_buttonStates[whichOne][event.jbutton.button] = true;
    }
    
    void InputHandler::InputHandler::clean()
    {
        if(m_bJoysticksInitialized)
        {
            for(unsigned int i = 0; i < (unsigned int)SDL_NumJoysticks(); i++)
            {
                SDL_JoystickClose(m_joysticks[i]);
            }
        }
    }

    ---Main.cpp---
    Code:
     
    #include <iostream>
    #include "game.h"
    
    const int FPS = 60;
    const int DELAY_TIME = 1000/FPS;
    
    int main(int argc, char* argv[])
    {
        Uint32 frameStart, frameTime;
    
        std::cout << "Game Init attempt...\n";
    
        if(TheGame::Instance()->init("Hello", 200, 100, 640, 480, false))
        {
            std::cout << "Game Init success!\n";
    
            while(TheGame::Instance()->running())
            {
                frameStart = SDL_GetTicks();
    
                TheGame::Instance()->handleEvents();
    
                TheGame::Instance()->update();
    
                TheGame::Instance()->render();
    
                frameTime = SDL_GetTicks() - frameStart;
    
                if((int)frameTime < DELAY_TIME)
                {
                    SDL_Delay((int)(DELAY_TIME - frameTime));
                }
            }
        }
        else
        {
            std::cout << "Initialization Failure: " << SDL_GetError() << "\n";
        }
        std::cout << "Closing game...\n";
        TheGame::Instance()->clean();
        return 0;
    }

    You can see in main() where a constant FPS is created using the difference between DELAYTIME and frameTime. I'm not sure if you've gotten to that part yet, if not just ignore it until you get to that part.

    That should be everything, good luck!

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

    A lot of thaaaaaanx :-)!!!!!!!!!!

    Quote Originally Posted by Alpo View Post
    I think we just happened to post on top of each other lol. Sure I can do that, the inputhandler might be a bit messy though. It's one of the largest files (and it really gets huge in my latest iterations).

    You can see in main() where a constant FPS is created using the difference between DELAYTIME and frameTime. I'm not sure if you've gotten to that part yet, if not just ignore it until you get to that part.

    That should be everything, good luck!

    Yeahh :-).. But I have to write some more posts, because I am allowed to write pn´s when I made 10 Posts.. :-D.. but..
    Alpo... you just really made my Day :-).. I think I´ve got now a really good Base to get through the next two chapters..
    I just tried to copy and paste, to see it´s working. But Vector2D isn´t implemented :-).. And Player.h and Enemy.h wanted me to implement SDL.h.

    But I think my next step tommorow eeeaaarly in the morning will be to check the differences between your and my .h and .cpp files..
    I´m so lucky that you gave me that Code.. I can´t tell how lucky you made me... Thanks a lot. I will gave you feedback tommorrow, and tell you what I find out :-).

    Thaaaanks again

    Sonntag69

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

    Thumbs up my Hero ... :-).. It worked :-)

    Yeaaahhhh!! :-)... I got my Version runnable.. But please don´t ask me, what my mistakes were.. *lol..

    I´m now through Chapter 4.. With Your help.. There are some things which I unfortunatelly not really understand..

    in two of your Codes you delcare a class instead incuding the h.-file.. It also works with including... But I don´t know why it is working with declare same class without Body in an other h.-file :-)..

    But ist working.. I can use Keyboard or Controller to move my Player :-)

    I will read later, on my way home (2.5 hours), so I will Review chapter 4 and preview chapter 5 and 6... I remember you told me, that chapter 5 would be a hard chapter..?? :-)..

    Maybe you can provide me, with your source-Code, again? And maybe you can give me some hints, where I should take care of?

    With your help, I think I could maybe go through that book in the next 3 Days..

    2 Days ago, I thought I could get the half of it... peeeerhaps... :-)..
    And now I´m relativly optimistic, again, that I can finish my Project in time :-).. You can´t guess how much you helped me already...!!!

    Best Regards

    Sonntag69

  7. #22
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Sonntag69 View Post
    Yeaaahhhh!! :-)... I got my Version runnable.. But please don´t ask me, what my mistakes were.. *lol..

    I´m now through Chapter 4.. With Your help.. There are some things which I unfortunatelly not really understand..

    in two of your Codes you delcare a class instead incuding the h.-file.. It also works with including... But I don´t know why it is working with declare same class without Body in an other h.-file :-)..

    But ist working.. I can use Keyboard or Controller to move my Player :-)

    I will read later, on my way home (2.5 hours), so I will Review chapter 4 and preview chapter 5 and 6... I remember you told me, that chapter 5 would be a hard chapter..?? :-)..

    Maybe you can provide me, with your source-Code, again? And maybe you can give me some hints, where I should take care of?

    With your help, I think I could maybe go through that book in the next 3 Days..

    2 Days ago, I thought I could get the half of it... peeeerhaps... :-)..
    And now I´m relativly optimistic, again, that I can finish my Project in time :-).. You can´t guess how much you helped me already...!!!

    Best Regards

    Sonntag69
    I think what you are referring to is called a "forward declaration". If you read the link I gave on what to include and why, it provides an explanation of when you should do this. Basically when a header only contains a pointer, or reference to a class, you can forward declare that class in the header, but you will need to #include that classes header in the source file if you want to use any of it's functions or whatever. A forward declaration just looks like this:

    Code:
    class GameObject; /// can be any class that has pointer or reference in the header
    I made a typo showing you how to access the InputHandler, you are supposed to use the scope resolution operator after the typedef alias, like this:

    Code:
    InputHandler::Instance()->getMouseButtonState(LEFT); // Returns true when left button clicked
    
    Vector2D vecMouse = InputHandler::Instance()->getMousePosition; /// Get mouse position
    The Vector2D class is probably one of the most useful things in the book (it should be right ahead of where you are), although there are a few convenience functions I would add to it.

    This is a method for the vector that can save you some typing, it returns true if the Point(Vector2D) is inside an SDL_Rect. It is good for Hit Testing:
    Code:
    bool Vector2D::isInside(const SDL_Rect& rect)
    {
        if(m_x < rect.x || m_x > rect.x + rect.w || m_y < rect.y || m_y > rect.y + rect.h)
        {
            return false;
        }
    
        return true;
    }
    For the full Vector2D class, I would just read on, it should be right ahead of where you are.

    The only major problem you are likely to hit soon is the GameStateMachine class. There's a logical error in the code where it will attempt to return you to the update function of a GameState that has already been deleted from the vector of GameStates in GameStateMachine. The solution is a system where you can mark a GameState as invalid (It's basically the same way you mark a GameObject as dead later on). You can see an implementation here:

    [C++] Following "SDL Game Development" book, state machine implemented in a way that crashes the application when a state is removed : learnprogramming

    Oh, and remember what I said about the Vector2D class a while back, the code he shows in the book for the class has an allocation problem somewhere. I can't remember exactly where, but hopefully if you read it with that in mind you can spot it.

    Good luck!

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

    Thumbs up I should have look here before searching :-)

    Quote Originally Posted by Alpo View Post
    I think what you are referring to is called a "forward declaration". If you read the link I gave on what to include and why, it provides an explanation of when you should do this. Basically when a header only contains a pointer, or reference to a class, you can forward declare that class in the header, but you will need to #include that classes header in the source file if you want to use any of it's functions or whatever. A forward declaration just looks like this:

    Code:
    class GameObject; /// can be any class that has pointer or reference in the header
    I made a typo showing you how to access the InputHandler, you are supposed to use the scope resolution operator after the typedef alias, like this:

    Code:
    InputHandler::Instance()->getMouseButtonState(LEFT); // Returns true when left button clicked
    
    Vector2D vecMouse = InputHandler::Instance()->getMousePosition; /// Get mouse position
    The Vector2D class is probably one of the most useful things in the book (it should be right ahead of where you are), although there are a few convenience functions I would add to it.

    This is a method for the vector that can save you some typing, it returns true if the Point(Vector2D) is inside an SDL_Rect. It is good for Hit Testing:
    Code:
    bool Vector2D::isInside(const SDL_Rect& rect)
    {
        if(m_x < rect.x || m_x > rect.x + rect.w || m_y < rect.y || m_y > rect.y + rect.h)
        {
            return false;
        }
    
        return true;
    }
    For the full Vector2D class, I would just read on, it should be right ahead of where you are.

    The only major problem you are likely to hit soon is the GameStateMachine class. There's a logical error in the code where it will attempt to return you to the update function of a GameState that has already been deleted from the vector of GameStates in GameStateMachine. The solution is a system where you can mark a GameState as invalid (It's basically the same way you mark a GameObject as dead later on). You can see an implementation here:

    [C++] Following "SDL Game Development" book, state machine implemented in a way that crashes the application when a state is removed : learnprogramming

    Oh, and remember what I said about the Vector2D class a while back, the code he shows in the book for the class has an allocation problem somewhere. I can't remember exactly where, but hopefully if you read it with that in mind you can spot it.

    Good luck!
    Hi Aldo,

    A few hours ago, i finished chapter 5... Since I was searching an error, which let my Programm Crash.. sometimes.. by changing the state.. a few minutes ago, i thought it could be, because the sdlgameobject::clean-function is empty..

    now i red your post.. *laugh.. Are you writing about the error I´ve got? :-D.. lool :-).. Thank you very much, if it is.. I will read it on my way home... And maybe programming at home.. my wife and my childs won´t like that :-).. but I´ve got to go through the book :-)

    Best Regards and thanks again

    Sonntag69

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

    Cool Good news and bad news

    Hi Alpo,
    here I am again.. :-)
    The good news, I just finished chapter 6.
    The Bad News 141 errors and 27 warnings...

    slowly I´m going to hesitate..

    There are so many errors, that I don´t know, where to start searching and correcting.. There are so many confusing things in this chapter...

    Could you do me a big, big favor and provide me with your checkpoint-files of this chapter?

    I don´t think, that I have a chance to get it running without help.. maybe if I had 2 weeks of time to search..

    It´s 10 p.m. and I´m learning since 5:30 a.m... and I can´t see anymore Code for today..

    I hope you are coming online and save me again :-)

    Sincerly

    Sonntag69 the hesit(h)ater :-D

  10. #25
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Sonntag69 View Post
    Hi Alpo,
    here I am again.. :-)
    The good news, I just finished chapter 6.
    The Bad News 141 errors and 27 warnings...

    slowly I´m going to hesitate..

    There are so many errors, that I don´t know, where to start searching and correcting.. There are so many confusing things in this chapter...

    Could you do me a big, big favor and provide me with your checkpoint-files of this chapter?

    I don´t think, that I have a chance to get it running without help.. maybe if I had 2 weeks of time to search..

    It´s 10 p.m. and I´m learning since 5:30 a.m... and I can´t see anymore Code for today..

    I hope you are coming online and save me again :-)

    Sincerly

    Sonntag69 the hesit(h)ater :-D
    Sorry, like I said I had to change so many things (not only because I wanted to make a different sort of program, but also because of all the problems with the code), it wouldn't line up with what the book has to say. You would basically have to change my code much more than you would have to change the books.

    My advice, just slow down, get rid of as many warnings as you can. Look up any errors the compiler gives you. Don't try to just copy code from the book, try to understand the concept behind what's going on (if you have a specific question, I'll try my best to help).

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

    caught me! :-)

    Quote Originally Posted by Alpo View Post
    Sorry, like I said I had to change so many things (not only because I wanted to make a different sort of program, but also because of all the problems with the code), it wouldn't line up with what the book has to say. You would basically have to change my code much more than you would have to change the books.

    My advice, just slow down, get rid of as many warnings as you can. Look up any errors the compiler gives you. Don't try to just copy code from the book, try to understand the concept behind what's going on (if you have a specific question, I'll try my best to help).
    Hi Alpo, you´re definitly right.
    Yesterday at home my main interest was to get that chapter working by copying that code, without really understanding, what it does.... caught me :-).. I thought I could do it that way and than learn in the bus and Train by reading it slowly on my 3 hours way to the Training course.. But that was a fallacy... What I learned by that way is, that it wasn´t a good way...

    I will follow your advice, slow down, accept that I can´t go through the book in time...

    I think at first I will do that Workaround you postet,
    and then begin with chapter 6 again.. more slowly but hopefully working :-)

    Best Regards

    Sonntag69

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

    Smile Almost finished for now

    Hi Alpo,

    I didn´t get the chapter 6. I worked it three times, but didn´t get it running..
    Instead of still wasting more time on this chapter, I used the Version with the workaround for making my presentation. I just fitted in a background, made the enemy-helicopter trying to catch the player, with slowly increasing velocity, and let the player control his helicopter by keyboard or controller.

    Tommorrow I have to present it via powerpointpresentation and the game itself. I allowed myself to mention your name on the last side by the notes of thanks.

    Unfortunatelly I think I can´t work on this Projekt next time, because on monday we start learning how to programm a windowsphone.. But perhaps some evenings.. we will see..

    Thanks again for your hints and helping hands.

    Best Regards

    Thomas Klaes

  13. #28
    Registered User Alpo's Avatar
    Join Date
    Apr 2014
    Posts
    877
    Quote Originally Posted by Sonntag69 View Post
    Hi Alpo,

    I didn´t get the chapter 6. I worked it three times, but didn´t get it running..
    Instead of still wasting more time on this chapter, I used the Version with the workaround for making my presentation. I just fitted in a background, made the enemy-helicopter trying to catch the player, with slowly increasing velocity, and let the player control his helicopter by keyboard or controller.

    Tommorrow I have to present it via powerpointpresentation and the game itself. I allowed myself to mention your name on the last side by the notes of thanks.

    Unfortunatelly I think I can´t work on this Projekt next time, because on monday we start learning how to programm a windowsphone.. But perhaps some evenings.. we will see..

    Thanks again for your hints and helping hands.

    Best Regards

    Thomas Klaes
    That sucks, thanks for mentioning me though.

    There's basically 3 things from the book you may want to remember and lookup for future use:

    1. XML Parsing - It basically allows you to store data for variables, you can use it for things like help menu's, buttons, character conversations, pretty much anything that you don't want to hardcode.

    2. ObjectFactory's - This is a method that allows you to create any type that you register with the base GameObjectFactory class. It's a pretty clever idea, and I've seen it used in other libraries (Window's uses something similar, if a lot more complicated I think ).

    3. TileMaps / TileMap Editors - A Tile Map Editor allows you to plot square units of a number of pictures into an XML File that your program can then parse and display the map. This is probably the most complicated thing in the book, but it makes creation of new levels very easy once done.

    That's all I can think of that you might be missing. Good luck in the future!

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

    Thumbs up

    Quote Originally Posted by Alpo View Post
    That sucks, thanks for mentioning me though.

    There's basically 3 things from the book you may want to remember and lookup for future use:

    1. XML Parsing - It basically allows you to store data for variables, you can use it for things like help menu's, buttons, character conversations, pretty much anything that you don't want to hardcode.

    2. ObjectFactory's - This is a method that allows you to create any type that you register with the base GameObjectFactory class. It's a pretty clever idea, and I've seen it used in other libraries (Window's uses something similar, if a lot more complicated I think ).

    3. TileMaps / TileMap Editors - A Tile Map Editor allows you to plot square units of a number of pictures into an XML File that your program can then parse and display the map. This is probably the most complicated thing in the book, but it makes creation of new levels very easy once done.

    That's all I can think of that you might be missing. Good luck in the future!
    Hehe.. that are exactly These chapters I couldn´t solve, because chapter 6 wasn´t working.. If have Time, I will find out, what the Problems were, and go on to work through the rest :-).

    I made my presentation and everyone loved it. I think I will get 100/100 Points for my work :-).

    best Regards

    Thomas Klaes

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