NMLTutorial/Road vehicle 32 bit sprites

From TTWiki
Jump to navigationJump to search

Now that you've seen that you can add 32 bit sprites, let's do that with an example. In fact we're going to pick up halfway down the road vehicle example from the beginning of this tutorial. We'll continue with what we had at the end of this page.

Example graphics

We'll be adding 32 bit graphics for the normal zoom level, including a recolour mask. From there we'll give you some pointers on how to add sprites for other zoom levels and you can easily fill in the rest yourself. So let's look at the graphics, shall we?


First, let's have a look again at the 8 bit sprites we already have for our road vehicle.

Empty flatbed truck sprites and flatbed trucks sprites loaded with a container


The 32 bit sprites are similar to the 8 bit sprites. The main difference is that to indicate transparancy you must use the real transparency of PNG files. If you use the blue background for transparency in 32 bit sprites, you'll get just that: a blue background. You may also use the alpha channel for semi-transparent pixels.

Empty flatbed truck sprites and flatbed trucks sprites loaded with a container in 32 bit.

Note that the sprite background is actually transparent. We've made the borders around the sprites blue, so that we can actually see where the indivual sprites are. This is not mandatory; as it doesn't end up in the game, you could have made it any other colour, even transparent if you like. We'll put this file in the gfx folder with the regular 8 bit sprites and name it flatbed_truck_1_goods_32.png‎.


Now even if you use the exact colours from the palette, this won't enable company colours in 32 bit sprites. For this you have to provide an additional 8 bit mask sprite, which does use the exact palette colours. Ingame, this mask is overlayed on top of the regular 32 bit sprites, which will give you a company-coloured vehicle. Note that the mask sprites need to be in exactly the same position as the regular 32 bit sprites, as they will use the same offsets!

The mask file to go with the previous 32 bit graphics

As we're now drawing in 8 bit again, we also have to use the magic blue to incidate transparent backgrounds! Also this file goes in the gfx directory and we'll name it flatbed_truck_1_goods_mask.png.


Spritesets

For the regular 8 bit sprites we have two spritesets in our NML code. Let's have a look at those again:

//graphics definition
spriteset(spriteset_flatbed_truck_1_goods_empty, "gfx/flatbed_truck_1_goods.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 0,      0,        8,    18,      -3,       -10]
    [ 16,     0,       20,    16,     -14,        -7]
    [ 48,     0,       28,    12,     -14,        -6]
    [ 96,     0,       20,    16,      -6,        -7]
    [ 128,    0,        8,    18,      -3,       -10]
    [ 144,    0,       20,    16,     -14,        -7]
    [ 176,    0,       28,    12,     -14,        -6]
    [ 224,    0,       20,    16,      -6,        -7]
}

spriteset(spriteset_flatbed_truck_1_goods_full, "gfx/flatbed_truck_1_goods.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 260,    0,        8,    18,      -3,      -10]
    [ 276,    0,       20,    16,     -14,       -7]
    [ 308,    0,       28,    12,     -14,       -6]
    [ 356,    0,       20,    16,      -6,       -7]
    [ 388,    0,        8,    18,      -3,      -10]
    [ 404,    0,       20,    16,     -14,       -7]
    [ 436,    0,       28,    12,     -14,       -6]
    [ 484,    0,       20,    16,      -6,       -7]
}

To define our 32 bit sprites, we have to define an alternative_sprites block to go with each of the spriteset blocks. The identifiers will be the same, we'll indicate that we have normal zoom sprites via ZOOM_LEVEL_NORMAL and that the sprites are 32 bit via BIT_DEPTH_32BPP.

We'll also reference the new graphics files. As the 32 bit sprites and the mask sprites belong together, they go together in in the same alternative_sprites block. Let's look at the first line of that block:

alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {

The positions, sizes and offsets of 32 bit sprites are incidentally the same as for the 8 bit sprites. Coincidence? Of course not, this will just save us a lot of trouble, as now we can simply copy these from the 8 bit sprites. This will give us the following alternative_sprites block for the first set of sprites:

alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 0,      0,        8,    18,      -3,       -10]
    [ 16,     0,       20,    16,     -14,        -7]
    [ 48,     0,       28,    12,     -14,        -6]
    [ 96,     0,       20,    16,      -6,        -7]
    [ 128,    0,        8,    18,      -3,       -10]
    [ 144,    0,       20,    16,     -14,        -7]
    [ 176,    0,       28,    12,     -14,        -6]
    [ 224,    0,       20,    16,      -6,        -7]
}


It is good practice to place the alternative_sprites block right after the spriteset block it belongs to. Let's do that and at the same time fill in the other alternative_sprites block.

//graphics definition
spriteset(spriteset_flatbed_truck_1_goods_empty, "gfx/flatbed_truck_1_goods.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 0,      0,        8,    18,      -3,       -10]
    [ 16,     0,       20,    16,     -14,        -7]
    [ 48,     0,       28,    12,     -14,        -6]
    [ 96,     0,       20,    16,      -6,        -7]
    [ 128,    0,        8,    18,      -3,       -10]
    [ 144,    0,       20,    16,     -14,        -7]
    [ 176,    0,       28,    12,     -14,        -6]
    [ 224,    0,       20,    16,      -6,        -7]
}
alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 0,      0,        8,    18,      -3,       -10]
    [ 16,     0,       20,    16,     -14,        -7]
    [ 48,     0,       28,    12,     -14,        -6]
    [ 96,     0,       20,    16,      -6,        -7]
    [ 128,    0,        8,    18,      -3,       -10]
    [ 144,    0,       20,    16,     -14,        -7]
    [ 176,    0,       28,    12,     -14,        -6]
    [ 224,    0,       20,    16,      -6,        -7]
}

spriteset(spriteset_flatbed_truck_1_goods_full, "gfx/flatbed_truck_1_goods.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 260,    0,        8,    18,      -3,      -10]
    [ 276,    0,       20,    16,     -14,       -7]
    [ 308,    0,       28,    12,     -14,       -6]
    [ 356,    0,       20,    16,      -6,       -7]
    [ 388,    0,        8,    18,      -3,      -10]
    [ 404,    0,       20,    16,     -14,       -7]
    [ 436,    0,       28,    12,     -14,       -6]
    [ 484,    0,       20,    16,      -6,       -7]
}
alternative_sprites(spriteset_flatbed_truck_1_goods_full, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    //left_x, upper_y, width, height, offset_x, offset_y
    [ 260,    0,        8,    18,      -3,      -10]
    [ 276,    0,       20,    16,     -14,       -7]
    [ 308,    0,       28,    12,     -14,       -6]
    [ 356,    0,       20,    16,      -6,       -7]
    [ 388,    0,        8,    18,      -3,      -10]
    [ 404,    0,       20,    16,     -14,       -7]
    [ 436,    0,       28,    12,     -14,       -6]
    [ 484,    0,       20,    16,      -6,       -7]
}

And that's really all there is to defining 32 bit sprites!

Templates

Can we also template 32 bit graphics, I hear you ask? Well certainly, they're no different than 8 bit sprites in that respect. Let's go back to where we've templated our example road vehicle. Because we were smart enough to keep the same positions, sizes and offsets for both our 8 bit and 32 bit sprites, we can simply use the same template we made earlier. This template was called tmpl_truck and has template parameters for the top left position of the first of eight sprites.

When first using this template, we simply replaced all the numbers inside the spriteset blocks with a call to the template, and ended up with this:

//graphics definition
spriteset(spriteset_flatbed_truck_1_goods_empty, "gfx/flatbed_truck_1_goods.png") {
    tmpl_truck(0, 0)
}

spriteset(spriteset_flatbed_truck_1_goods_full, "gfx/flatbed_truck_1_goods.png") {
    tmpl_truck(260, 0)
}

For our alternative_sprites blocks we can do the same, there's really nothing to it:

//graphics definition
spriteset(spriteset_flatbed_truck_1_goods_empty, "gfx/flatbed_truck_1_goods.png") {
    tmpl_truck(0, 0)
}
alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck(0, 0)
}

spriteset(spriteset_flatbed_truck_1_goods_full, "gfx/flatbed_truck_1_goods.png") {
    tmpl_truck(260, 0)
}
alternative_sprites(spriteset_flatbed_truck_1_goods_full, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck(260, 0)
}

So the first line of the blocks remains the same, we just replace the content with the template call.

Other zoom levels

For each additional zoom level, you simply add additional alternative_sprites blocks. Because of the different sprite sizes and offsets, you do have to create an additional template for each additional zoom level. If you order the sprites in a standardized way in your png files, you can keep reusing templates as we've done before.

Let's assume we have 32 bit graphics for the 4x zoom in level. The alternative_sprites for these sprites will be similar, but you specify the different zoom level (in this case) via ZOOM_LEVEL_IN_4X and reference the template you have made for sprites of this zoom level. For the first set of sprites you then get this additional alternative_sprites block:

alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck_zi4(0, 0)
}

And the total set of blocks:

//graphics definition
spriteset(spriteset_flatbed_truck_1_goods_empty, "gfx/flatbed_truck_1_goods.png") {
    tmpl_truck(0, 0)
}
alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck(0, 0)
}
alternative_sprites(spriteset_flatbed_truck_1_goods_empty, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck_zi4(0, 0)
}

spriteset(spriteset_flatbed_truck_1_goods_full, "gfx/flatbed_truck_1_goods.png") {
    tmpl_truck(260, 0)
}
alternative_sprites(spriteset_flatbed_truck_1_goods_full, ZOOM_LEVEL_NORMAL, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck(260, 0)
}
alternative_sprites(spriteset_flatbed_truck_1_goods_full, ZOOM_LEVEL_IN_4X, BIT_DEPTH_32BPP, "flatbed_truck_1_goods_32.png", "flatbed_truck_1_goods_mask.png") {
    tmpl_truck_zi4(260, 0)
}

And with that we end this example of adding 32 bit sprites to your road vehicle NewGRF. Of course, the same method as used here also applies to providing 32 bit alternatives for any other spriteset you may have. Now you can continue to learn how to replace base graphics.


NML Tutorial: Road vehicle 32 bit sprites