Legacy GM [solved] math behind nes tile_grids?

S

Shadowblitz16

Guest
hey it me again
I was just wondering the math behind the nes tilegrid
I know that it uses 8x8 tiles and can put them together to make bigger sprites
however I was wondering how they spaced their grids out

I have looked it up and it seems they have split their 1d tile grid up something like so
"i mod 8" <-- x
"i div 8" <-- y

however this only represents 1 pixel in between the index
I need to apply a space of 8 pixels to represent the tiles
 

johnwo

Member
Let's say you have 9 images that make up a tile.
The images make up the sprites like this:

Code:
|0|1|2|
|3|4|5|
|6|7|8|
1 is top-left, 2 is top-middle, and so on.

Coord to index:
Code:
i = x + gridWidth*y;
index of the image at [2,1] would be
Code:
2 + 3 * 1 = 5

Index to coord:
Code:
x = i mod gridWidth;
y = i div gridWidth;
The x/y of a image at the index of 5 would be:
Code:
x = 5 mod 3 = 2
y = 5 div 3 = 1

To draw the part, just do
Code:
draw_sprite_part(spr_tileGrid, -1, (i mod gridWidth) * 8, (i div gridWidth) * 8, (i mod gridWidth) * 8 + 8, (i div gridWidth) * 8 + 8, x, y);
// use draw_sprite_part, draw_background_part or a similar function, if applicable
Hope that clears thing up! :)

Cheers!
 
S

Shadowblitz16

Guest
@johnwo

so I have a array size of 0-255 each holding a 2 byte hex number
however I tried doing this and it only draws the strings out as 1 line and 8 columns
Code:
///draw TileMap
draw_set_font(fnt_nes)
draw_set_colour(c_white)

var i, xx, yy, val;
var map = global.TileMap
var size = array_length_1d(map)

for (i=0; i<size; i++) {
  xx = (i mod 128)*8
  yy = (i div 128)*8
  val = map
[I]  draw_text(xx+1, yy, val)
}
[code/][/I]
 
Last edited by a moderator:

johnwo

Member
First figure out what the width of your array is:
Code:
var width = sqrt(array_length_1d(map)); // A symmetrical 1D array of 256 elements would be equivalent to a 16x16 = 16^2 2D array.
Once you have that down, you can do this:
Code:
///draw TileMap
draw_set_font(fnt_nes)
draw_set_colour(c_white)

var i, xx, yy, val;
var map = global.TileMap; // I assume this is a standard 1D array
var size = array_length_1d(map);
var gridWidth = sqrt(array_length_1d(map)); // Get the width of the 1D array for converting to 2D.

for (i=0; i<size; i++) {
    xx = (i mod gridWidth);
    yy = (i div gridWidth);
    val = map[i];
    draw_text(xx*8, yy*8, val); // Multiply xx and yy by 8 to get the appropriate coords.
}
That should work.


Also, please use [ CODE ] [ /CODE ]-tags (no spaces between [ or ] and code or /code) when you post code, and if my posts are in any way helpful, and you feel I deserve it, please like the post.

Cheers!
 

johnwo

Member
Yea, that's because the array wasn't 0-255 like you said, but 0-127, i.e. 128-elements, which is not a perfect square... Use:
Code:
var gridWidth = 8; // any power of 2 will do...
Instead of
Code:
var gridWidth = sqrt(array_length_1d(map));
Cheers!
 
S

Shadowblitz16

Guest
@johnwo
can I ask you a question?
is it possible to split sprites up into pieces and store them into a array?
 

johnwo

Member
@johnwo
can I ask you a question?
is it possible to split sprites up into pieces and store them into a array?
Yes.

Do something like this:

Code:
var sprite_w = sprite_get_width(spr_sprite);// Sprite width
var sprite_h = sprite_get_height(spr_sprite);// Sprite height
var sprite_chunk = 8; // Sprite will be divided into 8x8 sprites
surf = surface_create(sprite_w,sprite_h);
surface_set_target(surf);
draw_clear_alpha(c_black,0);
draw_sprite(spr_sprite,0,0,0);
surface_reset_target();

sprite_array[(sprite_w+sprite_h)/sprite_chunk] = noone;
var i=0;

for (var xx=0;xx<;xx+=8) {
  for (var yy=0;yy<sprite_get_width(spr_sprite);yy+=8) {
      sprite_array[i++] = sprite_create_from_surface(surf,xx,yy,sprite_chunk,sprite_chunk,false,false,0,0);
  }
}
surface_free(surf);

// sprite_array[0..n], where n is the number of sprite parts, now contains the parts.
Doing something like this is ABHORRENTLY inefficient and should only be considered a curiosity, not a viable techique.

This code should run with little to no modification, however; I have not tested this code, and I will not do so either. If you're having problems with it, you're on your own.
Please mark the topic as solved if the question in the OP has been answered, and like any posts that helped you.

Cheers!
 

TheouAegis

Member
FYI, few NES games stored tiles in a 1:1 array. Many had condensed mapping where the tile ID would be preceded by the number of tiles to repeat. Many games used what are known as tile square assemblies. Each 2x2 assembly of tiles would be stored in an array, then each TSA would be mapped to the tile grid.


Haha! I had the threads listed backwards. Sorry for the necros.
 
Top