creating sprites from file: how to store tiles

Started by abstauber, Wed 05/05/2010 18:50:54

Previous topic - Next topic

abstauber

How would you store tiles which are going to be read by CreateFromExistingSprite:

a) all tiles in a row,  1 column
b) a few tiles in a row, a few columns

?

Lazy as I am, I'm doing method a at the moment, but could I get in trouble with a bitmap of 1600x16x8 ?

Thanks (as always)!

Ryan Timothy B

Why are you getting a sprite by using CreateFromExistingSprite and storing them?  Are you modifying them?

If you're not modifying them, just use DrawImage without storing them.

Khris

I assume this is for the map editor; it's supposed to be able to import maps thus tile data images, too.

abstauber

#3
Well, I create them with an external map editor. That way I can have a new tileset per level, without the need to import and map all sprites over and over again.
In other words, those sprites don't exist in the sprite manager.

edit: yup, as Khris said :)

Ryan Timothy B

Oh, so the images are stored in a text file and then created in AGS?  Otherwise I don't know why you're using CreateFromExistingSprite instead of CreateFromFile.
And if you are creating the image from a text file, you could also use SaveToFile instead of having to recreate them every time you start the game.


If I were to store a bunch of images, in memory in an organized fashion, I would do this:

Code: ags

enum eTileNames {
  ground,
  wall,
  platform, 
  water
};
#define tileAmount 4
eTileNames tileNames;
DynamicSprite* tiles[tileAmount];

//that way you can use
tiles[ground]=whatever...


And if I was using SaveToFile instead, I would change the array to a string and save the filename in it instead of the graphic.
Or am I still way off base here on understanding what you're asking for?

Khris

Abstauber creates his tilemaps with ProMotion. While it is primarily a PixelArt program, it supports creating tilemaps and allows to export them. The resulting files are a binary file holding the tilemap data and a PCX image holding the tiles.
Said image is by default as high as one tile and has all tiles next to each other in one long row. Thus exporting a map containing 100 different 16x16 tiles results in a 1600x16 image file.

It is possible to limit the width of the image to an arbitrary number of tiles, however this has two downsides: One can no longer determine the tile dimensions by reading the height of the image and one must use a slightly more complex method to grab a specific tile (thus abstauber's mentioning of him being lazy ;)).

So the question is: will one run into problems of the sort that the image might get too wide for AGS to import it properly?

Ryan Timothy B

Well then it isn't a tile anymore, they're combined tiles to make individual image strips.  Pretty much breaks all reasons of using tiles in the first place, doesn't it.

Khris

I think you misunderstood: say one were to create a primitive but very big map made of 100x70 tiles but only 4 different tile images. Exporting that in ProMotion results in a PCX that's 64x16 pixels. This PCX is then loaded into a DynamicSprite and separated into the 4 tiles again. Those are then drawn hundreds of times each to form the actual map made of 7000 tiles.
So while memory is no longer an issue, using tiles one can create big levels really fast.

My 2 cents on the original question:
It's probably better to limit the width to 50 or so tiles to be on the safe side. They're going to be of fixed size anyway, right?

Ryan Timothy B

#8
Yes I understand how tiled games work, I just didn't understand how promotion worked with the merging of all the individual tiles into one long sprite; plus I kept reading your post wrong.

I especially didn't understand why he'd be using CreateFromExistingSprite when I think it should be CreateFromDrawingSurface to make the newly cropped tile.  Wouldn't it be more on the CPU to store it the memory and then remove it for a cropped one?

This:
Code: ags

DynamicSprite* sprite = DynamicSprite.CreateFromFile("tilestrip.pcx");
if (sprite != null) {
  DrawingSurface *surface = sprite.GetDrawingSurface();
  int i;
  while (i<tileAmount) {
    tile[i] = DynamicSprite.CreateFromDrawingSurface(surface, i*16, 0, 16, 16);
    i++;
  }
  surface.Release();
  sprite.Delete();
}


Instead of:
Code: ags

DynamicSprite* sprite = DynamicSprite.CreateFromFile("tilestrip.pcx");
if (sprite != null) {
  int i;
  while (i<tileAmount) {
    tile[i] = DynamicSprite.CreateFromExistingSprite(sprite.Graphic);
    tile[i].Crop(i*16, 0, 16, 16);
    i++;
  }
  sprite.Delete();
}


Would that even make a noticeable difference with, let's say, 500 tiles?

abstauber

hehe, I'm glad I've overslept most of the discussion ;)

@Ryan
Even though I don't think most people will notice, your approach looks quite efficient. I think I'll change those few lines.


@Khris
Yep, the tile size is fixed - at least on a per-level base. But is there a "sientific" fact to limit the rowsize? Could I run in some kind of buffer overflow?

Btw. I've also convinced Mappy to create a compatible tile output. So if PM keeps crashing I might simply switch the editor.

SMF spam blocked by CleanTalk