Welcome, Guest. Please login or register. Did you miss your activation email?

Author Topic: [Solved]Loading from this tileset  (Read 13152 times)

0 Members and 1 Guest are viewing this topic.

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
[Solved]Loading from this tileset
« on: October 10, 2013, 05:17:20 pm »
Hello

I was following this tutorial on the SFML site and learnt how to load a tilemap fomr a tileset. But I have one problem - how to access tile from the tileset whose y-coordinate is not zero, ie, 1, 2, etc.

Example, if this is the tileset:


and I want to load the tiles of mario, how do I I do that?

Thanks

P.S.
I followed the tutorial and could understand how the tile class works. But is this tile class universally applicable for animated tiles and all?
« Last Edit: October 15, 2013, 04:26:28 pm by The illusionist mirage »

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Loading from this tileset
« Reply #1 on: October 10, 2013, 10:25:19 pm »

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
AW: Loading from this tileset
« Reply #2 on: October 10, 2013, 10:32:27 pm »
The tile map is just an example, it's not magic code that works for everything imaginary. What counts is the concept behind it.

With vertex arrays all you do is define the four edge points of the rectangle on a texture that you want to display. Imagine it as a paper with a cut-out rectangle that you move on an picture.

For animation you need changing frames every so often, thus instead of showing one point you simply move the "rectangle" from one animated frame to the next.

Now for your example map. Given that the data can't be easily calculated, you might want to define each frame/image/animation in a seperate file (i.e. writing down the ddge coordinates) and load and parse the data at runtime. How exactly is for you to figure out or use an existing format with existing loaders. ;)
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #3 on: October 11, 2013, 08:10:46 am »
Ok. I came across Tiled and could easily create a tilemap using it. So, how can I use the tilemap in my codes(in C++)? If anyone can link me t a tutorial, it'd be very helpful.

Thanks

Rhimlock

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
Re: Loading from this tileset
« Reply #4 on: October 11, 2013, 09:37:42 am »
Ok. I came across Tiled and could easily create a tilemap using it. So, how can I use the tilemap in my codes(in C++)? If anyone can link me t a tutorial, it'd be very helpful.

Thanks


You could take a look at this thread:

'Tiled' Tile-map Loader

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #5 on: October 12, 2013, 04:27:22 pm »
I have tried these threads(thread-1, thread-2) but I am unable to fully understand them. Until now, I had no problem with SFML or C++ but loading tilemaps is seeming pretty confusing to me.

I know this is a vague question but still I am asking it : how exactly is tilemap handling done in SFML and C++ using Tiled!

Can anyone please explain briefly to me the exact methods and algorithms used for loading and displaying tilemaps?

Thanks

Ancurio

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Loading from this tileset
« Reply #6 on: October 13, 2013, 02:52:15 pm »
I know this is a vague question but still I am asking it : how exactly is tilemap handling done in SFML and C++ using Tiled!

Can anyone please explain briefly to me the exact methods and algorithms used for loading and displaying tilemaps?

Thanks

For starters, you could just open a .tmx file and take a look yourself: Tiled saves maps as xml encoded strings of tile IDs (most commonly in cvs[comma separated values] form), where I believe 0 corresponds to "no tile" and from thereon tile ID 1 is the most top left tile in the tileset. The IDs cound up like you would read text, ie.

1, 2, 3, 4, 5, 6
7, 8, 9, 10, 11, 12 [etc]

so to map an ID to a tile, you have to do something like
Code: [Select]
int _id = id-1;
int tileX = (_id % mapWidth)*tileWidth; // 'mapWidth' in tiles, 'tileWidth/Height' in pixels
int tileY = (_id / mapWidth)*tileHeight;
and that's your pixel coordinates into the tileset.

Also note that Tiled supports multiple layers drawn on top of each other, so you will want to parse each layer separately.

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #7 on: October 13, 2013, 05:31:08 pm »
@Ancurio

This maybe irritating to you but I couldn't still understand what you just said. :(

Ancurio

  • Jr. Member
  • **
  • Posts: 66
    • View Profile
Re: Loading from this tileset
« Reply #8 on: October 13, 2013, 08:06:21 pm »
@Ancurio

This maybe irritating to you but I couldn't still understand what you just said. :(

I just looked into your original question again, and it seems all you want to do is animate a character sprite using a tileset that also holds tiles for composing the surrounding level/background.

In that case, thinking in terms of a tilemap is the wrong approach. All you want to do is create an sf::Sprite with the tileset sf::Texture attached to it, and then select the tile you want the sprite to display with ::setTextureRect(), feeding it the rectangle corresponding to the mario tiles. To animate, you'd simply call ::setTextureRect() again with the next animation tile and so on. Does that make sense?

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #9 on: October 14, 2013, 08:44:00 am »
Does that make sense?

Yes! Thanks! Now I could make my character move from a spritesheet within the screen.

Here's my spritesheet:


And here's my code:
#include <SFML/Graphics.hpp>

int main()
{
        sf::RenderWindow window(sf::VideoMode(640, 480), "tilemap_character_test", sf::Style::Close);

        enum Direction { Down, Left, Right, Up };

        sf::Vector2i source(1, Down);

        sf::Texture tex;
        if(!tex.loadFromFile("player2.png"))
        {
                system("pause");
                return EXIT_FAILURE;
        }
   
        sf::Sprite sprite;
        sprite.setTexture(tex);
        sprite.setTextureRect(sf::IntRect(32, 0, 32, 32));

        const float spriteSpeedX = 250.0f;
        const float spriteSpeedY = 250.0f;

        sf::Clock clock;
        float deltaTime = 0.f, currentTime = 0.f, previousTime = 0.f;

        float frameCounter = 0, switchFrame = 75, frameSpeed = 500;
        sf::Clock clock2;

    while (window.isOpen())
    {
                currentTime = clock.getElapsedTime().asSeconds();
                deltaTime = currentTime - previousTime;
                previousTime = currentTime;

                sf::Event event;
        while (window.pollEvent(event))
        {
            switch(event.type)
                        {
                                case sf::Event::Closed:
                                        window.close();
                                break;

                                case sf::Event::KeyPressed:
                                        if(event.key.code == sf::Keyboard::Escape)
                                                window.close();
                                break;
                        }
                       
        }
               
                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                        source.y = Direction::Up;
                        if(sprite.getPosition().y >= 0)
                                sprite.move(0, - spriteSpeedY * deltaTime);
                }

                else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Down))
                {
                        source.y = Direction::Down;
                        if(sprite.getPosition().y <= 448)
                                sprite.move(0, spriteSpeedY * deltaTime);
                }

                else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        source.y = Direction::Right;
                        if(sprite.getPosition().x <= 608)
                                sprite.move(spriteSpeedX * deltaTime, 0);
                }

                else if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        source.y = Direction::Left;
                        if(sprite.getPosition().x >= 0)
                                sprite.move(- spriteSpeedY * deltaTime, 0);
                }
               
                frameCounter += frameSpeed * clock2.restart().asSeconds();
                if(frameCounter >= switchFrame)
                {
                        frameCounter = 0;
                        if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up)
                                || sf::Keyboard::isKeyPressed(sf::Keyboard::Down)
                                        || sf::Keyboard::isKeyPressed(sf::Keyboard::Left)
                                                || sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                                source.x++;
               
                        if(source.x * 32 >= tex.getSize().x)
                                source.x = 0;
                }

                sprite.setTextureRect(sf::IntRect(source.x * 32, source.y * 32, 32, 32));

        window.clear();
                window.draw(sprite);
        window.display();
    }

        system("pause");
    return EXIT_SUCCESS;
}
 

And here's the output:




So, now how do I load a tilemap in which this sprite can move(and test for collisions etc). I don't need exact codes but only how I should make my approach and the methods involved.

Thanks for your help! :D

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #10 on: October 14, 2013, 09:13:11 am »
Here's a map that I've created:


Here are the tiles:


And here's my code:
#include <SFML/Graphics.hpp>

const int width = 640;
const int height = 480;
const int bpp = 32;
const char* title = "tilemap[test]_1";

const int H = 10;
const int W = 50;

sf::String tileMap[H] =
{
        "00000000000000000000000000000000000000000000000000",
        "0                                                0",
        "0                                                0",
        "0                                                0",
        "0                                                0",
        "0               MMM                              0",
        "0                                                0",
        "0                                                0",
        "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG",
        "GGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGGG"
};

int main()
{
    sf::RenderWindow window(sf::VideoMode(width, height, bpp), title, sf::Style::Close);

        sf::Texture tileset;
        if(!tileset.loadFromFile("tiles.png"))
        {
                system("pause");
                return EXIT_FAILURE;
        }

        sf::Sprite tile;
        tile.setTexture(tileset);

    while (window.isOpen())
    {
        sf::Event event;
        while (window.pollEvent(event))
        {
            if (event.type == sf::Event::Closed
                                || event.key.code == sf::Keyboard::Escape)
                                        window.close();
        }

        window.clear(sf::Color(107, 140, 255));

                for(int i = 0; i < H; i++)
                {
                        for(int j = 0; j < W; j++)
                        {
                                if(tileMap[i][j] == 'G')
                                        tile.setTextureRect(sf::IntRect(0 * 16, 0 * 16, 16, 16));

                                if(tileMap[i][j] == 'M')
                                        tile.setTextureRect(sf::IntRect(1 * 16, 0 * 16, 16, 16));
                               
                                if(tileMap[i][j] == '0' || tileMap[i][j] == ' ')
                                        continue;

                                tile.setPosition(sf::Vector2f(j * 16, i * 16));
                                window.draw(tile);
                        }
                }

        window.display();
    }

        system("pause");
    return EXIT_SUCCESS;
}
 

So, how do I use this tile map along with my character?

Thanks

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Loading from this tileset
« Reply #11 on: October 14, 2013, 09:26:12 am »
Umm...you look at where the player is, what tiles are close to him, what user input there is (if any), and decide what velocity he should have as a result?

It's probably not that complicated, and the exact answer depends entirely on what you want the program to do (like practically everything else in programming).  All we can do is throw out some obvious ideas, eg, if there is no solid tile directly underneath the player, maybe make him move downward.

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #12 on: October 14, 2013, 11:28:11 am »
Umm...you look at where the player is, what tiles are close to him, what user input there is (if any), and decide what velocity he should have as a result?

It's probably not that complicated, and the exact answer depends entirely on what you want the program to do (like practically everything else in programming).  All we can do is throw out some obvious ideas, eg, if there is no solid tile directly underneath the player, maybe make him move downward.

You mean what this thread here suggests?

I also got this idea from some site whose link I can't find(neither remember or find in browser history):

At any given instant, the player will have a minimum of 4 tiles adjacent to him. I can create a temporary variable and I'll check if the player can land in those coordinates. If he can I'll copy the temporary variable to that of player's position. If not, nothing happens. What do you think about this?

And I've decided that I'll keep the player falling and as soon as he touches those tiles, I'll stop his downward-Y movement(+ve direction Y movement). If he jumps, I'll try to implement gravity.

Thanks for the help!

Ixrec

  • Hero Member
  • *****
  • Posts: 1241
    • View Profile
    • Email
Re: Loading from this tileset
« Reply #13 on: October 14, 2013, 11:35:49 am »
If the player's position is represented by a simple pair of integers/floats, then a temporary variable probably isn't necessary (x++; and x--; aren't very expensive operations), but yes that is a perfectly good, simple and standard way of doing it, so go right ahead.

The Illusionist Mirage

  • Full Member
  • ***
  • Posts: 115
  • My Life = Linux, C++ & Computers
    • View Profile
    • fleptic
    • Email
Re: Loading from this tileset
« Reply #14 on: October 14, 2013, 06:18:57 pm »
Hi

my code is not producing the desired ouput. Here's my code:
/* Platformer try */

#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

float offsetX = 0, offsetY = 0;

const int H = 17;
const int W = 150;

sf::String tileMap[H] =
{
        "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
        "0                                                                                                                                                    0",
        "0                                                                                                                                                    0",
        "0                                                                                                                                                    0",
        "0                                                                                                                                                    0",
        "0                   w                                                                                                                                0",
        "0                                                                                                                                                    0",
        "0                                                                                                                                                    0",
        "0                      c                                                                                                                             0",
        "0                                                                                                                                                    0",
        "0                                                                                                                                                    0",
        "0               c    kckck                                                                                                                           0",
        "0G                                                                                                                                                   0",
        "0           d    g       d                                                                                                                           0",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
        "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP"
};

// Classes

/* Player */

class PLAYER
{
        public:
                float dy, dx;
                sf::FloatRect rect;
                bool onGround;
                sf::Sprite sprite;
                float currentFrame;

                PLAYER(sf::Texture &image);
                void update(float time);
                void Collision(int num);
                ~PLAYER();
};

PLAYER::PLAYER(sf::Texture &image)
{
        sprite.setTexture(image);
        rect = sf::FloatRect(100, 180, 16, 16);

        dx = dy = 0.1;
        currentFrame = 0;
}

void PLAYER::update(float time)
{
        rect.left += dx * time;
        Collision(0);

        if(!onGround)
                dy = dy + 0.0005 * time;

        rect.top += dy * time;
        onGround = false;
        Collision(1);

        currentFrame += time * 0.005;
       
        if(currentFrame > 3)
                currentFrame -= 3;

        if(dx > 0)
                sprite.setTextureRect(sf::IntRect(112 + 31 * int(currentFrame), 144, 16, 16));
        if(dx < 0)
                sprite.setTextureRect(sf::IntRect(112 + 31 * int(currentFrame) + 16, 144, -16, 16));

        sprite.setPosition(rect.left - offsetX, rect.top - offsetY);

        dx = 0;
}

void PLAYER::Collision(int num)
{
        for(int i = rect.top / 16; i < (rect.top + rect.height) / 16; i++)
        {
                for(int j = rect.left / 16; j < (rect.left + rect.width) / 16; j++)
                {
                        if(tileMap[i][j] == 'P' || tileMap[i][j] == 'k' || tileMap[i][j] == '0' || tileMap[i][j] == 'r' || tileMap[i][j] == 't')
                        {
                                if(dy > 0 && num == 1)
                                {
                                        rect.top = i * 16 - rect.height;
                                        dy = 0;
                                        onGround = true;
                                }

                                if(dy < 0 && num == 1)
                                {
                                        rect.top = i * 16 + 16;
                                        dy = 0;
                                }

                                if(dx > 0 && num == 0)
                                {
                                        rect.left = j * 16 - rect.width;
                                }

                                if(dx < 0 && num == 0)
                                {
                                        rect.left = j * 16 + 16;
                                }
                        }
                }
        }
}

PLAYER::~PLAYER()
{
        // dctor
}

class ENEMY
{
        public:
                float dx, dy;
                sf::FloatRect rect;
                sf::Sprite sprite;
                float currentFrame;
                bool onGround;
                bool life;

                void set(sf::Texture &image, int x, int y);
                void update(float time);
                void Collision();
                ~ENEMY();
};

void ENEMY::set(sf::Texture &image, int x, int y)
{
        sprite.setTexture(image);
        rect = sf::FloatRect(x, y, 16, 16);

        dx = 0.05;
        currentFrame = 0;
        life = true;
}

void ENEMY::update(float time)
{
        rect.left += dx * time;

        Collision();
       
        currentFrame  += time * 0.005;

        if(currentFrame > 2)
                currentFrame -= 2;
       
        sprite.setTextureRect(sf::IntRect(18 * int(currentFrame), 0, 16, 16));

        if(!life)
                sprite.setTextureRect(sf::IntRect(58, 0, 16, 16));

        sprite.setPosition(rect.left - offsetX, rect.top - offsetY);
}

void ENEMY::Collision()
{
        for(int i = rect.top / 16; i < (rect.top + rect.height); i++)
        {
                for(int j = rect.left / 16; j < (rect.left + rect.width); j++)
                {
                        if(tileMap[i][j] == 'p' || tileMap[i][j] == '0')
                        {
                                if(dx > 0)
                                {
                                        rect.left = j * 16 - rect.width;
                                        dx *= -1;
                                }

                                else if(dx < 0)
                                {
                                        rect.left = j * 16 + 16;
                                        dx *=- 1;
                                }
                        }
                }
        }
}

ENEMY::~ENEMY()
{
        // dctor
}

int main()
{
    sf::RenderWindow window(sf::VideoMode(400, 250, 32), "Platformer_try[mario]");

        sf::Texture tileSet;
        tileSet.loadFromFile("Mario_tileset.png");

        PLAYER Mario(tileSet);

        ENEMY Mushy;
        Mushy.set(tileSet, 48 * 16, 13 * 16);

        sf::Sprite tiles;
        tiles.setTexture(tileSet);

        sf::SoundBuffer buffer;
        buffer.loadFromFile("Jump.ogg");
       
        sf::Sound sound(buffer);

        sf::Music music;
        music.openFromFile("Mario_Theme.ogg");
        //music.play();

        sf::Clock clock;

    while (window.isOpen())
    {
                float time = clock.getElapsedTime().asMicroseconds();
                clock.restart();

                time = time / 500;

                if(time > 20)
                        time = 20;
               
                sf::Event event;
        while(window.pollEvent(event))
        {
                        if(event.type == sf::Event::Closed || event.key.code == sf::Keyboard::Escape)
                window.close();
        }

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
                {
                        Mario.dx =- 0.1f;
                }

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
                {
                        Mario.dx = 0.1f;
                }

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
                {
                        if(Mario.onGround)
                        {
                                Mario.dy =- 0.27f;
                                Mario.onGround = false;
                                //sound.play();
                        }
                }

                Mario.update(time);
                //Mushy.update(time);

                if(Mario.rect.intersects(Mushy.rect))
                {
                        if(Mushy.life)
                        {
                                if(Mario.dy > 0)
                                {
                                        Mushy.dy = 0;
                                        Mario.dy = -0.2;
                                        Mushy.life = false;
                                }

                                else
                                {
                                        Mario.sprite.setColor(sf::Color::Red);
                                }
                        }
                }
               
                if(Mario.rect.left > 200)
                        offsetX = Mario.rect.left - 200;


        window.clear(sf::Color(107, 140, 225));

                for(int i = 0; i < H; i++)
                {
                        for(int j = 0; j < W; j++)
                        {
                                if(tileMap[i][j] == 'P')
                                        tiles.setTextureRect(sf::IntRect(143 - 16 * 3, 112, 16, 16));

                                if(tileMap[i][j] == 'k')
                                        tiles.setTextureRect(sf::IntRect(143, 112, 16, 16));

                                if(tileMap[i][j] == 'c')
                                        tiles.setTextureRect(sf::IntRect(143 - 16, 112, 16, 16));

                                if(tileMap[i][j] == 't')
                                        tiles.setTextureRect(sf::IntRect(0, 47, 32, 95 - 47));

                                if(tileMap[i][j] == 'g')
                                        tiles.setTextureRect(sf::IntRect(0, 16 * 9 - 5, 3 * 16, 16 * 2 + 5));

                                if(tileMap[i][j] == 'G')
                                        tiles.setTextureRect(sf::IntRect(145, 222, 222 - 145, 255 - 222));

                                if(tileMap[i][j] == 'd')
                                        tiles.setTextureRect(sf::IntRect(0, 106, 74, 127 - 106));

                                if(tileMap[i][j] == 'w')
                                        tiles.setTextureRect(sf::IntRect(99, 224, 140 - 99, 255 - 224));

                                if(tileMap[i][j] == 'r')
                                        tiles.setTextureRect(sf::IntRect(143 - 32, 112, 16, 16));

                                if(tileMap[i][j] == '0' || tileMap[i][j] == ' ')
                                        continue;

                                tiles.setPosition(sf::Vector2f(j * 16 - offsetY, i * 16 - offsetX));
                                window.draw(tiles);
                        }
                }

                window.draw(Mario.sprite);
                //window.draw(Mushy.sprite);
        window.display();
    }

    return 0;
}
 

My mario goes correctly upto some extent but then suddenly, he starts to move in the positive y-direction.







But I can still jump and move around as if I was moving normally(I can even jump), but only the movement is actually in y-direction.

I was following code from here which I found on this forum a few days ago(this code works correctly):
#include <SFML/Graphics.hpp>
#include <SFML/Audio.hpp>

float offsetX = 0, offsetY = 0;

const int H = 17;
const int W = 150;

sf::String TileMap[H] =
{
    "000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000",
    "0                                                                                                                                                    0",
    "0                                                                                    w                                                               0",
    "0                   w                                  w                   w                                                                         0",
    "0                                      w                                       kk                                                                    0",
    "0                                                                             k  k    k    k                                                         0",
    "0                      c                                                      k      kkk  kkk  w                                                     0",
    "0                                                                       r     k       k    k                                                         0",
    "0                                                                      rr     k  k                                                                   0",
    "0                                                                     rrr      kk                                                                    0",
    "0               c    kckck                                           rrrr                                                                            0",
    "0                                      t0                           rrrrr                                                                            0",
    "0G                                     00              t0          rrrrrr            G                                                               0",
    "0           d    g       d             00              00         rrrrrrr                                                                            0",
    "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
    "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
    "PPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPPP",
};

class PLAYER
{
    public:

    float dx,dy;
    sf::FloatRect rect;
    bool onGround;
    sf::Sprite sprite;
    float currentFrame;

    PLAYER(sf::Texture &image)
    {
        sprite.setTexture(image);
        rect = sf::FloatRect(100, 180, 16, 16);

        dx = dy = 0.1;
        currentFrame = 0;
    }

    void update(float time)
    {
        rect.left += dx * time;
        Collision(0);

        if(!onGround)
            dy = dy + 0.0005 * time;

        rect.top += dy * time;
        onGround = false;
        Collision(1);

        currentFrame += time * 0.005;
        if(currentFrame > 3)
            currentFrame -= 3;

        if(dx > 0)
            sprite.setTextureRect(sf::IntRect(112 + 31 * int(currentFrame), 144, 16, 16));
        if(dx < 0)
            sprite.setTextureRect(sf::IntRect(112 + 31 * int(currentFrame) + 16, 144, -16, 16));

        sprite.setPosition(rect.left - offsetX, rect.top - offsetY);

        dx = 0;
    }

    void Collision(int num)
    {
        for(int i = rect.top / 16; i < (rect.top + rect.height) / 16; i++)
            for (int j = rect.left / 16; j < (rect.left + rect.width) / 16; j++)
                        {
                if((TileMap[i][j] == 'P')
                    || (TileMap[i][j] == 'k')
                        || (TileMap[i][j] == '0')
                            || (TileMap[i][j] == 'r')
                                || (TileMap[i][j] == 't'))
                {
                    if(dy > 0 && num == 1)
                    {
                        rect.top = i * 16 - rect.height;
                        dy = 0;
                        onGround = true;
                    }

                    if(dy < 0 && num == 1)
                    {
                        rect.top = i * 16 + 16;
                        dy = 0;
                    }

                    if(dx > 0 && num == 0)
                    {
                        rect.left =  j * 16 -  rect.width;
                    }

                    if(dx < 0 && num == 0)
                    {
                        rect.left =  j * 16 + 16;
                    }
                }

                if(TileMap[i][j] == 'c')
                {
                     //TileMap[i][j]=' ';
                }
                         }

    }

};

class ENEMY
{
    public:
        float dx,dy;
        sf::FloatRect rect;
        sf::Sprite sprite;
        float currentFrame;
        bool life;

        void set(sf::Texture &image, int x, int y)
        {
            sprite.setTexture(image);
            rect = sf::FloatRect(x, y, 16, 16);

            dx = 0.05;
            currentFrame = 0;
            life = true;
        }

        void update(float time)
        {
            rect.left += dx * time;

            Collision();

            currentFrame += time * 0.005;
            if(currentFrame > 2)
                currentFrame -= 2;

            sprite.setTextureRect(sf::IntRect(18 * int(currentFrame), 0, 16, 16));

            if(!life)
                sprite.setTextureRect(sf::IntRect(58, 0, 16, 16));

            sprite.setPosition(rect.left - offsetX, rect.top - offsetY);

        }

        void Collision()
        {
            for (int i = rect.top / 16; i < (rect.top + rect.height) / 16; i++)
                for(int j = rect.left / 16; j < (rect.left + rect.width) / 16; j++)
                    if((TileMap[i][j] == 'P') || (TileMap[i][j] == '0'))
                    {
                        if(dx > 0)
                        {
                            rect.left = j * 16 - rect.width;
                            dx *= -1;
                        }

                                                else if(dx < 0)
                        {
                            rect.left = j * 16 + 16;
                            dx *=- 1;
                        }
                    }
        }
};

int main()
{

    sf::RenderWindow window(sf::VideoMode(400, 250), "Super Mario");

        sf::Texture tileSet;
        tileSet.loadFromFile("Mario_Tileset.png");

        PLAYER Mario(tileSet);
        ENEMY  enemy, enemy2;

        enemy.set(tileSet, 48*16, 13*16);

        sf::Sprite tile(tileSet);

        sf::SoundBuffer buffer;
        buffer.loadFromFile("Jump.ogg");
        sf::Sound sound(buffer);

    sf::Music music;
    music.openFromFile("Mario_Theme.ogg");
    //music.play();

        sf::Clock clock;

    while(window.isOpen())
    {
                float time = clock.getElapsedTime().asMicroseconds();
                clock.restart();

                time = time / 500;  // &#1079;&#1076;&#1077;&#1089;&#1100; &#1088;&#1077;&#1075;&#1091;&#1083;&#1080;&#1088;&#1091;&#1077;&#1084; &#1089;&#1082;&#1086;&#1088;&#1086;&#1089;&#1090;&#1100; &#1080;&#1075;&#1088;&#1099;

                if(time > 20)
            time = 20;

        sf::Event event;
        while(window.pollEvent(event))
        {
            if(event.type == sf::Event::Closed)
                window.close();
                }

                if(sf::Keyboard::isKeyPressed(sf::Keyboard::Left))
            Mario.dx =- 0.1;

            if(sf::Keyboard::isKeyPressed(sf::Keyboard::Right))
            Mario.dx = 0.1;

            if(sf::Keyboard::isKeyPressed(sf::Keyboard::Up))
            if(Mario.onGround)
            {
                Mario.dy =- 0.27;
                Mario.onGround = false;
                //sound.play();
            }

                 Mario.update(time);
                 enemy.update(time);

                 if(Mario.rect.intersects(enemy.rect))
                 {
             if(enemy.life)
             {
                 if(Mario.dy > 0)
                 {
                     enemy.dx = 0;
                     Mario.dy =- 0.2;
                     enemy.life = false;
                 }
                 else Mario.sprite.setColor(sf::Color::Red);
                         }
                 }

                 if(Mario.rect.left > 200)
            offsetX = Mario.rect.left - 200;           //&#1089;&#1084;&#1077;&#1097;&#1077;&#1085;&#1080;&#1077;

                 window.clear(sf::Color(107, 140, 255));

                 for(int i = 0; i < H; i++)
                         for(int j = 0; j < W; j++)
                          {
                                if(TileMap[i][j] == 'P')
                    tile.setTextureRect(sf::IntRect(143 - 16 * 3, 112, 16, 16));

                                if(TileMap[i][j] == 'k')
                    tile.setTextureRect(sf::IntRect(143, 112, 16, 16));

                            if(TileMap[i][j] == 'c')
                    tile.setTextureRect(sf::IntRect(143 - 16, 112, 16, 16));

                                if(TileMap[i][j] == 't')
                    tile.setTextureRect(sf::IntRect(0, 47, 32, 95 - 47));

                                if(TileMap[i][j] == 'g')
                    tile.setTextureRect(sf::IntRect(0, 16 * 9 - 5, 3 * 16, 16 * 2 + 5));

                                if(TileMap[i][j] == 'G')
                    tile.setTextureRect(sf::IntRect(145, 222, 222 - 145, 255 - 222));

                            if(TileMap[i][j] == 'd')
                    tile.setTextureRect(sf::IntRect(0, 106, 74, 127 - 106));

                                if(TileMap[i][j] == 'w')
                    tile.setTextureRect(sf::IntRect(99, 224, 140 - 99, 255 - 224));

                                if(TileMap[i][j] == 'r')
                    tile.setTextureRect(sf::IntRect(143 - 32, 112, 16, 16));

                                if((TileMap[i][j] == ' ') || (TileMap[i][j] == '0'))
                    continue;

                            tile.setPosition(j * 16 - offsetX, i * 16 - offsetY);
                        window.draw(tile);
                     }

                window.draw(Mario.sprite);
            window.draw(enemy.sprite);
            window.draw(enemy2.sprite);

                window.display();
    }

    return 0;
}
 

How exactly does this collision and update functions work? And what mistakes are therein my code?

Thanks