Jump to content

  • Log In with Google      Sign In   
  • Create Account


Player Spritesheet Problems


Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.

  • You cannot reply to this topic
1 reply to this topic

#1 Dante12129   Members   -  Reputation: 1036

Like
0Likes
Like

Posted 02 May 2013 - 04:21 PM

I am making a tile-based game using C++ and SDL. I've been writing a library to make certain parts of it easier. My current problem is that I have a player that has a spritesheet that has images for each possible direction. Its dimensions are 128x32, with each sprite being 32x32. The rpoblem is that if i try to access anything besides the sprite at the first position at vector, it doesn't return an image. I also have a spritesheet for the terrain, but it renders fine no matter which sprite I choose, but it is 512x512.

 

Spritesheet.hpp

#ifndef SPRITESHEET_HPP_INCLUDED
#define SPRITESHEET_HPP_INCLUDED

#include <vector>
#include "Image.hpp"
#include "Primitives.hpp"
#include "General.hpp"

/**
 * \file
 * \brief File that contains everything needed to load nad handle a spritesheet.
 * \author Dante12129
 * \version 1.0
 */

 namespace grnbll
 {
     class Spritesheet : public Applyable
     {
         public:
            //Constructors and destructor
            Spritesheet();
            Spritesheet(std::string filename, unsigned int width, unsigned int height, unsigned int sprite_width, unsigned int sprite_height);
            ~Spritesheet();

            //Getters
            unsigned int GetSpriteWidth();
            unsigned int GetSpriteHeight();
            Rectangle& GetSprite(int spritenumber);
            SDL_Surface* GetSurface();

            //Manipulation Functions
            int MakeTransparent(uint8_t r, uint8_t g, uint8_t b);

         private:
            //Container of all the coordinates of the images
            std::vector<Rectangle> sprites;

            //Height and width of the whole image
            unsigned int whole_width, whole_height;
            //Height and width of a single sprite
            unsigned int m_sprite_width, m_sprite_height;

            //The image of the spritesheet
            Image m_img_whole;

            //Number of sprites in the image
            int m_num_of_sprites, m_sprites_per_row, m_sprites_per_column;

            //The name of the spritesheet for the file
            std::string m_filename;

     };
 }

#endif // SPRITESHEET_HPP_INCLUDED

 

Spritesheet.cpp

 

#include "Spritesheet.hpp"

//Spritesheet
//Constructors and destructor
grnbll::Spritesheet::Spritesheet()
{
    //Initalize all sizes to 0
    whole_width = 0; whole_height = 0; m_sprite_width = 0; m_sprite_height = 0;
    m_num_of_sprites = 0; m_sprites_per_row = 0; m_sprites_per_column = 0;
    //The image and vector don't contain anything
    //Set the filename to nothing
    m_filename = "";
}
grnbll::Spritesheet::Spritesheet(std::string filename, unsigned int width, unsigned int height, unsigned int sprite_width, unsigned int sprite_height)
{
    //Initalize the sizes
    whole_width = width; whole_height = height; m_sprite_width = sprite_width; m_sprite_height = sprite_height;
    m_sprites_per_row = whole_width/m_sprite_width; m_sprites_per_column = whole_height/m_sprite_height; m_num_of_sprites = m_sprites_per_row*m_sprites_per_column;
    //Initialize the image
    m_img_whole = Image(width, height, filename);
    //Initialize the vector so that sprites can be accessed
    if(m_sprites_per_column == 1)
    {
        for(int i = 0; i < m_sprites_per_row; i++)
        {
            sprites.push_back(Rectangle(i*m_sprite_width, 0, m_sprite_width, m_sprite_height));
        }
    }
    else if(m_sprites_per_row == 1)
    {
        for(int i = 0; i < m_sprites_per_column; i++)
        {
            sprites.push_back(Rectangle(0, i*m_sprite_width, m_sprite_width, m_sprite_height));
        }
    }
    else
    {
        for(int i = 0; i < m_sprites_per_row; i++)
        {
            for(int j = 0; j < m_sprites_per_column; j++)
            {
                sprites.push_back(Rectangle(j*m_sprite_width, i*m_sprite_height, m_sprite_width, m_sprite_height));
            }
        }
    }
}
grnbll::Spritesheet::~Spritesheet() = default;

//Getters
unsigned int grnbll::Spritesheet::GetSpriteWidth() { return m_sprite_width; }
unsigned int grnbll::Spritesheet::GetSpriteHeight() { return m_sprite_height; }
grnbll::Rectangle& grnbll::Spritesheet::GetSprite(int spritenumber){ return sprites.at(spritenumber); }
SDL_Surface* grnbll::Spritesheet::GetSurface() { return m_img_whole.GetSurface(); }

//Manipulation functions
int grnbll::Spritesheet::MakeTransparent(uint8_t r, uint8_t g, uint8_t b)
{
    return m_img_whole.MakeTransparent(r, g, b);
}

 

Player.hpp

 

#ifndef PLAYER_HPP_INCLUDED
#define PLAYER_HPP_INCLUDED

#include "New_Engine.hpp"

namespace survgame
{
    enum class Directions
    {
        Up = 3,
        Down = 1,
        Left = 2,
        Right = 0
    };

    class Player : public grnbll::Applyable
    {
        public:
            //Constructors and destructor
            Player(int start_x, int start_y, Directions starting_direction, std::string filename);
            ~Player();

            //Getters
            int GetX();
            int GetY();
            int GetXOld();
            int GetYOld();

            //Setters
            void SetX(int x);
            void SetY(int y);
            void SetXOld(int x);
            void SetYOld(int y);

            //Handlers
            void HandleEvents(grnbll::Event& event);
            SDL_Surface* GetSurface();
            grnbll::Rectangle& GetDirection();

        private:
            //Position variables
            int x_pos, y_pos;
            int x_old, y_old;
            Directions facing_direction;

            //The spritesheet for the player
            grnbll::Spritesheet player_sprites;
    };
}

#endif // PLAYER_HPP_INCLUDED

 

Player.cpp

 

#include "Player.hpp"

//Player
//Constructors and destructor
survgame::Player::Player(int start_x, int start_y, Directions starting_direction, std::string filename)
{
    //Initialize the positions and the direction.
    x_pos = start_x; y_pos = start_y;
    x_old = start_x; y_old = start_y;
    facing_direction = starting_direction;

    //Load the spritesheet.
    player_sprites = grnbll::Spritesheet(filename, 128, 32, 32 ,32);
    player_sprites.MakeTransparent(0xED, 0x0B, 0xB5);
}
survgame::Player::~Player() = default;

//Getters
int survgame::Player::GetX() { return x_pos; }
int survgame::Player::GetY() { return y_pos; }
int survgame::Player::GetXOld() { return x_old; }
int survgame::Player::GetYOld() { return y_old; }

//Setters
void survgame::Player::SetX(int x) { x_pos = x; }
void survgame::Player::SetY(int y) { y_pos = y; }
void survgame::Player::SetXOld(int x) { x_old = x; }
void survgame::Player::SetYOld(int y) { y_old = y; }

//Handlers
void survgame::Player::HandleEvents(grnbll::Event& event)
{
    x_old = x_pos;
    y_old = y_pos;
    if(event.GetOther().other == grnbll::OtherEvents::KeyPress)
    {
        switch(event.GetKeyboard().key)
        {
            case grnbll::Keys::Left:
                x_pos--;
                facing_direction = Directions::Left;
                break;
            case grnbll::Keys::Right:
                x_pos++;
                facing_direction = Directions::Right;
                break;
            case grnbll::Keys::Up:
                y_pos--;
                facing_direction = Directions::Up;
                break;
            case grnbll::Keys::Down:
                y_pos++;
                facing_direction = Directions::Down;
                break;
        }
    }
}
SDL_Surface* survgame::Player::GetSurface() { return player_sprites.GetSurface(); }
grnbll::Rectangle& survgame::Player::GetDirection() { return player_sprites.GetSprite(0); }

 

main.cpp

 

#include <fstream>
#include <cstdlib>
#include "New_Engine.hpp"
#include "Player.hpp"

int main ( int argc, char* argv[] )
{
    //Variables necessary to the screen and program
    grnbll::Screen screen(512, 612, "Game");
    grnbll::Event event;
    grnbll::FPSRegulator fps(60); fps.Start();
    bool running = true;

    //Spritesheets
    grnbll::Spritesheet terrain("Terrain.png", 512, 512, 32, 32);
    terrain.MakeTransparent(0xED, 0x0B, 0xB5);

    //Map file
    std::ifstream map_file("World1.map");

    //Player Info
    survgame::Player player(4, 0, survgame::Directions::Down, "Player.png");

    //Others

    //Load the map
    int map_array[16][16];
    for(int i = 0; i < 16; i++)
    {
        for(int j = 0; j < 16; j++)
        {
            char current_map_piece;
            map_file >> current_map_piece;
            map_array[j][i] = current_map_piece - '0';
        }
    }

    //Setup the screen
    screen.SetBackgroundColor(SDL_MapRGB(SDL_GetVideoSurface()->format, 0xFF, 0xFF, 0xFF));
    if(map_file.is_open())
    {
        for(int i = 0; i < 16; i++)
        {
            for(int j = 0; j < 16; j++)
            {
                screen.Apply(terrain, j*32, i*32, terrain.GetSprite(map_array[j][i]));
            }
        }
        screen.Flip();
    }

    while(running)
    {
        //Event handling
        while(event.Poll())
        {
            if(event.GetOther().other == grnbll::OtherEvents::Quit)
            {
                running = false;
            }
            player.HandleEvents(event);
        }

        //Logic
        if(map_array[player.GetX()][player.GetY()] == 3)
        {
            running = false;
        }

        //Rendering
        if((player.GetX() > 15) || (player.GetX() < 0) || (player.GetY() > 15) || (player.GetY() < 0) || (map_array[player.GetX()][player.GetY()] == 1))
        {
            player.SetX(player.GetXOld());
            player.SetY(player.GetYOld());
            screen.Apply(player, player.GetX()*32, player.GetY()*32, player.GetDirection());
            screen.Flip();
        }
        else
        {
            screen.Apply(terrain, player.GetXOld()*32, player.GetYOld()*32, terrain.GetSprite(map_array[player.GetXOld()][player.GetYOld()]));
            screen.Apply(player, player.GetX()*32, player.GetY()*32, player.GetDirection());
            screen.Flip();
        }

        fps.Delay();
    }

    return 0;
}

 

The rectangles are constructed like (x, y, w, h).

The apply function takes a reference to an Applyable class so that it can get a pointer for blitting, the x and y positions to blit, and then a rectangle of what part of the source image to blit.

 

If I replace the "0" in Player::GetDirection() with an int between one and three or static_cast<int>(facing_direction), it won't give me the correct part of the spritesheet. I was wondering if this has to do with the player spritesheet having its sprite height and whole height equal instead of the terrain spritesheet, where they aren't equal.

 



Sponsor:

#2 Dante12129   Members   -  Reputation: 1036

Like
0Likes
Like

Posted 02 May 2013 - 07:05 PM

I got it working. I had forgotten I had hardcoded sprite widths and heights into the Apply method instead of getting them from the rectangle that is passed.






Old topic!
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.



PARTNERS