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

Author Topic: Tile Map  (Read 16747 times)

0 Members and 1 Guest are viewing this topic.

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Tile Map
« on: May 27, 2017, 04:52:40 pm »
Hello, I want to make a side scroller, and I don't know how to make the map(I mean the grass,dirt and the other things that you stay on), I did this with a map made in photoshop, but it was really big so I decided to do it differently, I heard of "tiles", so I downloaded a spritesheet with the dirt and the others(dimentions, 70x70 per sprite).I made it to only show a sprite from the spritesheet.But I don't know how to make an entire map out of it,how to multiply the sprites?
Guess Who's Back ?

eXpl0it3r

  • SFML Team
  • Hero Member
  • *****
  • Posts: 11034
    • View Profile
    • development blog
    • Email
Re: Tile Map
« Reply #1 on: May 27, 2017, 07:58:51 pm »
You can use a vertex array of quads that define a tile each.

You write some simple file how the level should look like, then you load the file and fill the vertex array with quads that point to the correct tile on your spritesheet texture.
Official FAQ: https://www.sfml-dev.org/faq.php
Official Discord Server: https://discord.gg/nr4X7Fh
——————————————————————
Dev Blog: https://duerrenberger.dev/blog/

Hapax

  • Hero Member
  • *****
  • Posts: 3379
  • My number of posts is shown in hexadecimal.
    • View Profile
    • Links
Re: Tile Map
« Reply #2 on: May 28, 2017, 02:19:30 am »
Remember that there is an example of how to create a simple tile map in the official SFML tutorials.
Selba Ward -SFML drawables
Cheese Map -Drawable Layered Tile Map
Kairos -Timing Library
Grambol
 *Hapaxia Links*

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #3 on: May 28, 2017, 09:38:31 am »
Can you please explain me how the vertex array positions(and the texture positions) work ? I mean what dimensions  to write in the parentheses ?
Guess Who's Back ?

Elias Daler

  • Hero Member
  • *****
  • Posts: 599
    • View Profile
    • Blog
    • Email
Re: Tile Map
« Reply #4 on: May 28, 2017, 02:06:18 pm »
This guide will help you.
By the way, if you have questions, please open it in "Help" forum subsection. This section is made for showing off projects you're working on.
Tomb Painter, Re:creation dev (abandoned, doing other things) | edw.is | @EliasDaler

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #5 on: May 28, 2017, 04:54:49 pm »
Ok somehow I did it, but the "map" is blurry, why?
Guess Who's Back ?

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #6 on: May 28, 2017, 05:38:27 pm »
I think I found the solution... I expanded 70x70 texture to a 800x70 texture, but how to put 1 by 1(I mean how to put like 11 70x70 squares)?
Guess Who's Back ?

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #7 on: May 29, 2017, 04:01:13 pm »
Elias, the example isn't for a spritesheet ?, I have the sprites individually...
« Last Edit: May 29, 2017, 04:11:34 pm by Boanc »
Guess Who's Back ?

GameBear

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
    • Email
Re: Tile Map
« Reply #8 on: May 29, 2017, 04:21:36 pm »
There are multiple ways to do this, but the easy way is with a 2d array for the map info, and a "print" function for drawing.
Posido code:

//Array
int mapArray[4][5] =
    {
        {0,0,0,0,0},
        {0,1,1,1,0},
        {1,2,2,2,1},
        {2,2,2,2,2},
    };
//Some sprites
SF::sprite airSp....
SF::sprite grassSp....
SF::sprite dirtSp....

//Let's say all sprites are 8 by 8 pixels
Int spriteSize = 8;

//Render it
Window.beginDraw();
for(int i = 0; i < 4; i++){
for(int j = 0; j < 5; j++){
If(mapArray[i][j] == 0) {
  airSp.setPosition(i*spriteSize,j*SpriteSize);
  Window.draw(airSp);
}
Else If(mapArray[i][j] == 1) {
  grassSp.setPosition(i*spriteSize,j*SpriteSize);
  Window.draw(grassSp);
}

Else If(mapArray[i][j] == 2) {
  dirtSp.setPosition(i*spriteSize,j*SpriteSize);
  Window.draw(dirtSp);
}

}
}
Window.display();
 


Please note, this is posido code, not actual code.
Also, wrote iron my phone, so errors are most likely.... But the algorithm should be sound.
string message = "some random dude";
cout << "I'm just " << message;

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #9 on: May 29, 2017, 04:58:54 pm »
Hmm...something is not right the window opens for a second and it closes(Note:The console remains opened)...that's the code....
#include <SFML/Graphics.hpp>
using namespace sf;

int main()
{
    RenderWindow window(VideoMode(800,600),"Platformer");
    window.setFramerateLimit(60);
    window.setVerticalSyncEnabled(1);
    View view(FloatRect(0,0,800,600));
    Clock clock;
    int mapArray[4][5] =
    {
        {0,0,0,0,0},
        {0,0,0,0,0},
        {0,0,0,0,0},
        {1,1,1,1,1},
    };
    Texture TTileGrass;
    TTileGrass.loadFromFile("Textures/Map/Grass/slice03_03.png");
    TTileGrass.setSmooth(1);
    Sprite STileGrass;
    STileGrass.setTexture(TTileGrass);
    Texture TAdventurer;
    TAdventurer.loadFromFile("Textures/Characters/Adventurer/adventurer_tilesheet.png");
    TAdventurer.setSmooth(1);
    Sprite SAdventurer;
    SAdventurer.setTexture(TAdventurer);
    SAdventurer.setTextureRect(IntRect(0,0,80,110));
    SAdventurer.setPosition(0,440);
    Vector2f pos = SAdventurer.getPosition();
    while(window.isOpen() && !Keyboard::isKeyPressed(Keyboard::Return))
    {
        clock.restart();
        Event event;
        while(event.type == Event::Closed)
        {
            window.close();
        }
    window.clear();
    if(Keyboard::isKeyPressed(Keyboard::Up))
    {
        pos.y -= 5;
    }
    if(Keyboard::isKeyPressed(Keyboard::Left))
    {
        pos.x -= 5;
        view.move(-5,0);
    }
    if(Keyboard::isKeyPressed(Keyboard::Right))
    {
        pos.x += 5;
        view.move(5,0);
    }
    SAdventurer.setPosition(pos.x,pos.y);
    window.setView(view);
    window.draw(SAdventurer);
    for(int i = 0;i<4;i++)
    {
        for(int j = 0; j<5;i++)
    {
        if(mapArray[i][j] == 1)
        {
            STileGrass.setPosition(i * 70, j * 70);
            window.draw(STileGrass);
        }
    }
    }
    window.display();
    }
}
 
« Last Edit: May 29, 2017, 05:56:18 pm by Boanc »
Guess Who's Back ?

AFS

  • Full Member
  • ***
  • Posts: 115
    • View Profile
Re: Tile Map
« Reply #10 on: May 29, 2017, 07:35:11 pm »
Hmm...something is not right the window opens for a second and it closes

You have to put your logic and drawing code inside a loop. Also, you are polling the events incorrectly. It should be like this:


#include <SFML/Graphics.hpp>
using namespace sf;

int main()
{

    // Your variables, like windows, textures and sprites, go outside the loop.
    RenderWindow window(VideoMode(800,600),"Platformer");
   
    (...)

    // Then you start the game loop.
    while( window.isOpen() )
    {

        // First you poll the events inside ANOTHER loop.

        Event event;
        while ( window.pollEvent(event) )
        {

             // The following should be "if", not "while" as you put in your code.
             if( event.type == Event::Closed )  
             {
                    window.close();
             }

        }

        // Now you do the rest of your code.

        if(Keyboard::isKeyPressed(Keyboard::Up))
        {
            pos.y -= 5;
        }
       
        (...)

        // Finally you draw.

        window.clear( sf::Color::White ) // You have to clear the window first, you forgot about this.

        window.setView(view);
        window.draw(SAdventurer);
        for(int i = 0;i<4;i++)
        {
            for(int j = 0; j<5;i++)
        {
            if(mapArray[i][j] == 1)
            {
                STileGrass.setPosition(i * 70, j * 70);
                window.draw(STileGrass);
            }
        }

        window.display();

    }

}
 

I really recommend reading and understanding the tutorials, otherwise you'll run into problems every five minutes, and we won't always be able to help you in time.
« Last Edit: May 29, 2017, 07:39:59 pm by AFS »

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #11 on: May 29, 2017, 07:43:47 pm »
Ok AFS, I did exactly how you said, but when I start the program it shows me "Platformer.exe has stopped working",why?
PS:I commented the for loop section and it worked, something is wrong with the for loops,but I don't have any idea what...
PSS:The code :
#include <SFML/Graphics.hpp>
using namespace sf;

int main()
{
    RenderWindow window(VideoMode(800,600),"Platformer");
    window.setFramerateLimit(60);
    window.setVerticalSyncEnabled(1);
    View view(FloatRect(0,0,800,600));
    int mapArray[4][5] =
    {
        {0,0,0,0,0},
        {0,0,0,0,0},
        {0,0,0,0,0},
        {1,1,1,1,1},
    };
    Texture TTileGrass;
    TTileGrass.loadFromFile("Textures/Map/Grass/slice03_03.png");
    TTileGrass.setSmooth(1);
    Sprite STileGrass;
    STileGrass.setTexture(TTileGrass);
    Texture TAdventurer;
    TAdventurer.loadFromFile("Textures/Characters/Adventurer/adventurer_tilesheet.png");
    TAdventurer.setSmooth(1);
    Sprite SAdventurer;
    SAdventurer.setTexture(TAdventurer);
    SAdventurer.setTextureRect(IntRect(0,0,80,110));
    SAdventurer.setPosition(0,440);
    Vector2f pos = SAdventurer.getPosition();
    while(window.isOpen() && !Keyboard::isKeyPressed(Keyboard::Return))
    {
        Event event;
        while(window.pollEvent(event))
    {
        if(event.type == Event::Closed)
        {
            window.close();
        }
    }
    if(Keyboard::isKeyPressed(Keyboard::Up))
    {
        pos.y -= 5;
    }
    if(Keyboard::isKeyPressed(Keyboard::Left))
    {
        pos.x -= 5;
        view.move(-5,0);
    }
    if(Keyboard::isKeyPressed(Keyboard::Right))
    {
        pos.x += 5;
        view.move(5,0);
    }
    window.clear(Color::White);
    SAdventurer.setPosition(pos.x,pos.y);
    window.setView(view);
    window.draw(SAdventurer);
    for(int i = 0;i<4;i++)
    {
        for(int j = 0; j<5;i++)
    {
        if(mapArray[i][j] == 1)
        {
            STileGrass.setPosition(i * 70, j * 70);
            window.draw(STileGrass);
        }
    }
    }
    window.display();
    }
}
 
« Last Edit: May 29, 2017, 07:47:50 pm by Boanc »
Guess Who's Back ?

GameBear

  • Jr. Member
  • **
  • Posts: 73
    • View Profile
    • Email
Re: Tile Map
« Reply #12 on: May 29, 2017, 09:03:00 pm »
for(int j = 0; j<5;i++)

The last i should be a j in this one :)
string message = "some random dude";
cout << "I'm just " << message;

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #13 on: May 29, 2017, 09:19:36 pm »
Oh, sorry that was the problem thanks!  :P You are the best!  ;D
Guess Who's Back ?

Ionut

  • Jr. Member
  • **
  • Posts: 59
  • Guess Who's Back ?
    • View Profile
    • Email
Re: Tile Map
« Reply #14 on: May 29, 2017, 09:33:48 pm »
But...how to change the mapArray to be like 0,530( I mean the map itself), because it is at 0,0
PS:I changed the Map array to : int mapArray[4][5] =
    {
        {1,0,0,0,0},
        {1,0,0,0,0},
        {1,0,0,0,0},
        {1,0,0,0,0},
    };
To show it horrizontally,not vertically, but it is in the left corner up(0,0) and I want it in the left corner down(0,530)
Guess Who's Back ?