Re: 8x16 sprite is really a 16x32 pixel image?
Posted: Fri Sep 28, 2012 3:17 pm
Yes, tokumaru, that makes sense to me.tokumaru wrote:If you have a level, you should have a level map. Storing straight name/attribute table is not efficient at all, even if you compress each screen, because you don't take advantage of all the redundancy of blocks that repeat.unregistered wrote:Wat is the level map? What info does it hold other than the metatile index? I don't think I have a level map.
A level map is usually a 2D grid of metatiles, where each byte is a metatile index. The level map can be used both for rendering (read a row/column of metatiles from the map, use their indexes to load the tiles that make up the metatiles and write them to VRAM) and for collision (get the metatile index and use it to get the metatile's collision information).
Here's a straightforward representation of a level that uses 32x32-pixel (4x4 tiles) metatiles:See how everything connects? Whenever you want to check what is present at a certain map location, you convert the coordinates into an index which you can use to read a metatile index from the level map. Once you know the metatile's index, you can use it to get any information you want about it. If you are rendering the background, read from the MatatileTileXX tables and and write the tile indexes to the name tables, and the attributes to the attribute tables. If you're testing for collisions, read from the MetatileCollision table to know how the objects should react to the metatile.Code: Select all
;16 tiles for each of the 4 metatiles ;metatile: $00 $01 $02 $03 MatatileTile00: .db $00, $04, $08, $0c MatatileTile01: .db $00, $04, $09, $0c MatatileTile02: .db $00, $04, $0a, $0c MatatileTile03: .db $00, $04, $0a, $0c MatatileTile10: .db $00, $05, $0b, $0d MatatileTile11: .db $00, $05, $0a, $0c MatatileTile12: .db $00, $05, $0a, $0c MatatileTile13: .db $00, $05, $0b, $0d MatatileTile20: .db $00, $06, $06, $0e MatatileTile21: .db $00, $06, $06, $0c MatatileTile22: .db $00, $06, $06, $0c MatatileTile23: .db $00, $06, $06, $0e MatatileTile30: .db $00, $07, $07, $0f MatatileTile31: .db $00, $07, $07, $0f MatatileTile32: .db $00, $07, $07, $0f MatatileTile33: .db $00, $07, $07, $0f MatatileAttributes: ;4 palette indexes for each metatile .db %00000000 ;palettes for metatile $00 .db %01010101 ;palettes for metatile $01 .db %01010000 ;palettes for metatile $02 .db %11000011 ;palettes for metatile $03 MetatileCollision: ;%00 = air, %01 = solid, %10 = water, %11 = hazard .db %00000000 ;metatile $00 is all air .db %01010101 ;metatile $01 is all solid .db %01010000 ;only the top of metatile $02 is solid .db %11110101 ;the top of metatile $03 hursts the player, the bottom is solid LevelMap01: ;this small level is 16x8 metatiles (512x256 pixels) large .db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 .db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 .db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 .db $00, $00, $00, $00, $00, $02, $02, $00, $00, $00, $00, $00, $00, $00, $00, $00 .db $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $02, $02 .db $00, $00, $00, $01, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00, $00 .db $01, $01, $01, $01, $00, $00, $00, $00, $00, $01, $01, $01, $03, $03, $01, $01 .db $01, $01, $01, $01, $00, $00, $01, $01, $01, $01, $01, $01, $01, $01, $01, $01
Se how one thing points to another, that points to another and so on? This is how you manage to reuse your level data effectively compressing it to much less than it would be if you had raw name/attribute table data. The data above is just 200 bytes. If I were to represent that in uncompressed form, this 2-screen wide level would have been 2048 bytes large.
Anyway, this is not a lesson about compression (although the maps are indeed compressed), this is to show you one of the possible ways in which a level can be represented, and how you can access everything on it. Does this make sense to you?