How to load level files in SDL2 from Tiled map editor


#1

Hello everyone, I’m a bit new to game dev and I was wondering if any of you new how to load level files in SDL2 possibly using SDL_Surface. I was also wondering how would SDL2 recognise the data through a 2D array and what extension do I need to save the Tiled map as??

for those who are wondering what language I’m using it is C…

and yeah that’s about it. Please, if anyone knows reply to this, feel free to reply here

Thanks in advance, Miles


#2

You should probably remove your email so that bots don’t get it and start spamming it like crazy.

SDL2 does not have any features that do what you want at this time. You’ll have to make something like that or find a framework that does it for you and use SDL2 for graphics, events, and possibly more. SDL2 is basically a wrapper framework to make cross-platform programs so that you don’t have to change anything when compiling for different OSs.


#3

You don’t understand, i’m doing it a different way. I’m not expecting anything from the SDL2 it has be done from scratch using SDL2


#4

SDL 2.0 API by Category
You can load files with the functions in the “File Abstraction” category, but decoding/interpreting them will have to be something you program. SDL2 does not understand the concept of a level file. All files are simply streams of data to SDL2 that you can read from or write to, (if you have the permissions to do so). If you want to load images, SDL_Image can be used to open, decode, and create surfaces from files, but then they’re just surfaces to SDL2 and not “levels”. File extensions are just like the filenames, they simply tell us what they are, and while OSs will usually open a program based on the file extension, they can be ignored.

And, I’m being serious when I say that you should remove your email. Anyone/Anything can view this board, so spammers can get your email address and start sending junk to it.


#5

Thanks mate, i did i decided in order to do that SDL2 would need to read off of the file. So i’d use the function SDL_RWFromFile which is from the File Abstraction category. Which basically does what it says in the function (read or write from the file)…however i want SDL2 to render and understand it so how would i do that?


#6

If they’re standard images, then you’ll need to use something like SDL_Image to load the images into surfaces. After that, you’ll need to use the Video category of the wiki to create a window, and then draw to the window.

This tutorial for SDL2 will help you a lot faster than I can.


#7

So load the tiles first? (i know how to use SDL_Image i’ve used it before) then load the level file so it understands??? wait what??


#8

So as I said I decided that i want it to read off of a file rather than using a 2D array (if that’s possible) so this is what I did:

typedef struct Object {
int w, h;
SDL_Texture *multiTexture[13][13];
} Object;

Object level[13][13];

int main(int argc, char *argv[])
{

Object object;  // already did the set up things above...
SDL_Surface *surface = NULL;
surface = IMG_Load("spriteSheet.png");
object.multiTexture[0][0] = SDL_CreateTextureFromSurface(renderer,      surface);
SDL_FreeSurface(surface);

FILE *fp = fopen("my_file.txt", "rb");
SDL_RWops *rw = SDL_RWFromFP(fp, SDL_TRUE);
SDL_RWclose(rw);

   int quit = 0;
while(!quit) {
    SDL_Event event;
    if(SDL_PollEvent(&event)) {
        if(event.type == SDL_QUIT) {
            quit = 1;
        }
    }
}

/* the rest of the stuff i’d just free the texture etc. */
}

Now I’m just asking am I on the right lines from there? my_file is binary which is the level data for the file.

I also decided to make a sprite of everything (this saves a lot of typing)…
If I’m not please tell me what i’m doing wrong


#9

First of all, do you mind showing an example of how your level file is constructed?
By doing so, it might help us coming up with a solution on how to parse the level files and then render the tiles in the window.


#10

the text file contains the data in binary (hence why I wrote “rb” for the file)

its garbage but i’ll show you:

000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000111111111111111111111111111111111111111111111111111111111111
111111111111111111111111111111111111111111111111111111111111

This is basically supposed to render the ground from Mario
As I said, just plain garbage made up of 0s and 1s 1 being where the tile is supposed to be and 0 being where there’s nothing.


#11

Now that I understand the level-file’s format, here’s a question regarding the code in your last post:
why do you have a multi-dimensional array of SDL_Texture’s in your Object struct?
See below.

typedef struct Object {
int w, h;
SDL_Texture *multiTexture[13][13];
} Object;

You should only need to load 1 texture, which contains all the different tile types. Also, that texture doesn’t need to be placed inside each object (tile). Just load it outside and use that texture whenever the tiles should be rendered.

Beside’s that, what exactly is it you’re having troubles with?
Is the issue with parsing the level file or rendering the tiles?


#12

Ok so this?

typedef struct Object {
int w, h;
SDL_Texture *multiTexture;
} Object;

I’m having troubles with rendering the tiles and parsing the level file, I want it to recognise the tiles (as you know it’s reading from the binary level file


#13

I will try explain this as easy as possible because I think your confused about how this is going to work.

The 1’s and 0’s in the array are only used to let you know which texture should be drawn. You should not have an array of textures to draw a level, you should have an array of numbers or characters to tell you which texture should be used to draw,

Or if you take Naiths advice which is the correct approach I believe you should have all your tiles inside one texture. Then the value inside the array will decide the source rectangle of the texture.

Example. Sudo Code

int myLevel[2][2] = { {0, 1}, {1, 1} };
void draw() {
    for(int i = 0; i < 2; ++i) {
        for(int j = 0; j < 2; ++i) {
            if (myLevel[i][j] == 0) {
                // SDL_RenderCopy with the texture for ID 0
            } else if (myLevel[i][j] == 1) {
                // SDL_RenderCopy with the texture for ID 1
            }
        }
    }
}

#14

Oh my gosh you’re life saver I’ll try and do that on my computer to see thanks


#15

Now that i think about it, that also seems wrong, I want it to read off of the file data instead of manual inputting the data inside the 2D array. How would I come across that?

I’m also using a sprite sheet which contains the tiles and character images


#16

Example

Your texture contains a strip of tiles like this,
[X][O][T][E]

SDL_Rect source{0, 0, tileWidth, tileHeight}

for( int i = 0; i < TileRows; i++) {
    for( int j = 0; j < TileCols; j++) {
        // Set the rectangle of the tileID from the 2Darray we want to draw
        source.x = level[j][i] * tileWidth;
        // SDL_RenderCopy(renderer, tex, source, dest); 
    }
}

So if tile ID = 0 were going to draw [X] tile
if tile ID = 2 were going to draw [T] tile


#17

What? so when do we render the tile it has be done in the render function i made, it holds all the rects and stuff for the characters.
I don’t understand what you mean “if the tile ID = 0” when would it be zero do you mean:
source.x = level[0][0] * tileWidth?
or
source.x = level[i][j] * 0?
what do you mean?


#18

Rendering uses 2 rectangles.
Dest Rect is where it will appear on the screen.
Source Rect is how much of the texture you want to draw.

Example
int myLevel[2][2] = { {0, 1}, {1, 1}
Lets say our texture is 100 pixels in width and 10 pixels in height and contains 10 tiles. Each tile is 10 * 10.

Tile0 is {0,0,10,10}
Tile1 is {10,0,10,10}
Tile2 is {20,0,10,10}

myLevel[0][0] = 0

That means that our source rect is going to be
the same as tile0 {0,0,10,10}

This only works if all tiles have the same y value inside the texture on the same line.
Multiplying the value we get back from our 2D array by the tile width will give us the position of the tile texture we need.
source.x = level[j][i] * tileWidth;

What our texture looks like.
[0][1][2][3][4][5][6][7][8][9]

So if level[10][13] = 4
Then 4 * tilewidth which is 10 = 40.
Source.x = 40 which is Tile4


#19

Uhhhh I sorta understood that, I guess. You kinda got a little confusing when you started saying what the texture looks like and when you started saying level[10][13] = 4…why does it equal a value?? you should explain in more detail what we’re doing here? do you mean initialising it? or what? also where did you get Tile0, Tile1, Tile2 from?
it’s just those things that need to be explained.

I still don’t think you get what i want my program to do:
I want it to read the tiles from the text file so that it can display the level, i’m using a sprite sheet so I guess i’d have to use an array.

what would i do for that would i just do:

int falseNum = 0;
if(!falseNum) { /* don’t display tile / } else { / do something and display the tile */}

How would it recognise the tile?

if this is right, how would i do that something that i want my game program to do?
Explain in detail, as i said i’m new to game developing.


#20

Naith, please help me on this