Day 70/100 100 Days of Code

Day 70/100 100 Days of Code

Rebuild Back Better

In the session, I focused on developing the player object. Initially, I created an Entity class. After that, I created another class named Player. The Player class inherits the attributes of the Entity.

Each in-game Entity will have the same attributes and its own behaviour.

class Entity
{
public:
    unsigned int health;
    unsigned int damage;
    unsigned int resourceLoad;
    unsigned int level;
    int x, y;
};

Each attribute should be quite obvious The resourceLoad attribute is the amount of resources an Entity can carry.

template<typename STRING, typename SURFACE, typename RENDERER>
class Player: public Entity
{    
public:
    SURFACE *cursorImage;
    bool LoadPlayerImages(STRING location);
    void ShowDefaultCursor(RENDERER *renderer);
    void ShowInteractableCursor();
    void ShowCanAttackCursor();
};

This is the Player object with a new attribute and its methods. I have completed the ShowDefaultCursor and for now the LoadPlayerImages method loads only the default cursor.

template<>
bool Player<std::string, SDL_Surface, SDL_Renderer>::LoadPlayerImages(std::string location)
{
    cursorImage = IMG_Load(location.c_str());

    if (cursorImage == nullptr)
    {
        return false;
    }
    return true;
}

template<>
void Player<std::string, SDL_Surface, SDL_Renderer>::ShowDefaultCursor(SDL_Renderer *renderer)
{
    SDL_Surface *convertImage = SDL_ConvertSurface(cursorImage, cursorImage->format);

    if (convertImage == nullptr)
    {
        std::cout << "Failed to create default cursor ";
        std::cout << SDL_GetError() << std::endl;
        exit(-1);
    }

    SDL_Texture *defaultcursorTexture = SDL_CreateTextureFromSurface(renderer, convertImage);

    const SDL_FRect defaultCursorHolder = {    static_cast<float>(x), 
                                            static_cast<float>(y), 
                                            static_cast<float>(convertImage->w/50), 
                                            static_cast<float>(convertImage->h/50)};


    SDL_RenderTexture(renderer, defaultcursorTexture, nullptr, &defaultCursorHolder);    
    SDL_DestroyTexture(defaultcursorTexture);
    SDL_DestroySurface(convertImage);
}

Declaration and Definition

// game.h
static Player<std::string, SDL_Surface, SDL_Renderer> *player;

//game.cpp
Player<std::string, SDL_Surface, SDL_Renderer> *Game::player = nullptr;

Instantiation

player = new Player<std::string, SDL_Surface, SDL_Renderer>;

if (!player->LoadPlayerImages(execpath + std::string("/Contents/Resources/graphics/Player/cursor_main.png")))
{
    std::cout << "Failed to load cursor image ";
    std::cout << IMG_GetError() << std::endl;
    return false;
}

// Hide the cursor    
int getSDLHideCursorVal = SDL_HideCursor();

if (getSDLHideCursorVal != 0)
{
    std::cout << "Failed to hide cursor";
    std::cout << SDL_GetError() << std::endl;
    return false;
}

Now that everything is ready and the computer's cursor is hidden, we can display the image in the position where the mouse should be located.

player->x = mouseX;
player->y = mouseY;
player->ShowDefaultCursor(renderer);

The Object will be updated to show the corresponding image which depends on what type of object it is hovering.

💡
IIt's important to remember that the origin point of each image is at the top left corner. This is especially crucial when editing non-static images like cursors.

Demonstration