_Tommo_
|
|
« Reply #9 on: August 23, 2011, 06:01:35 PM » |
|
I will add my method here, it's similar to what was posted above but it allows for rotated sprites Also, everything is pre-cached and is blazing fast! Premise: everything only has smooth transitions with grass, which in my game is perfectly fine. Also, under some conditions corner neighboring tiles are ignored (reducing by a lot the amount of needed tiles). Hash Building phase (done with another program): 1) I made a list of the "unrotated type tiles", using their neighbour distribution, etc: zero, one, two at opposite sides, two at a corner, three at a corner etc. 2) Each tile type was assigned a bitmask, where each "1" in it is a required equal neighbour. This assigned a number from 0 to 256 to each tile, used to index an hashmap and store the tile type and rotation (0). Eg: a straight road has two neighbours, one north and one south, and its hash is 01000100 = 34. Each tile hashcode is then bit-rotated-with-carry by 2, to account for rotated version of the same tiles. The resulting hashcode was used to store the original tile type in the hashmap, and an increased tile rotation (1-3). Eg: the same road from before, but horizontal, has an hashcode of 00010001 = 136, and a rotation of 1. 3) then I do something even uglier and trickier to ignore all the neighbours combinations where a corner neighbour is not adjacent to two side neighbours, eg: this Is hashed the same as this And then both the rotation and tile type hash are printed to screen in a C array form. Then, at runtime, I use this exceedingly magical code, that computes the hash code for the current tile and tells it its tile version and rotation: static const char tileHash[] = { 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 3, 3, 1, 1, 6, 6, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 3, 3, 1, 1, 6, 6, 1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 8, 8, 1, 1, 2, 2, 1, 1, 2, 2, 6, 6, 7, 7, 6, 6, 9, 9, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 3, 3, 1, 1, 6, 6, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 3, 3, 1, 1, 6, 6, 1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 4, 4, 3, 3, 8, 8, 1, 1, 2, 2, 1, 1, 2, 2, 6, 6, 7, 7, 6, 6, 9, 9, 1, 1, 3, 6, 1, 1, 3, 6, 2, 2, 4, 8, 2, 2, 7, 9, 1, 1, 3, 6, 1, 1, 3, 6, 2, 2, 4, 8, 2, 2, 7, 9, 3, 3, 4, 7, 3, 3, 4, 7, 4, 4, 5, 10, 4, 4, 10, 11, 3, 3, 4, 7, 3, 3, 4, 7, 8, 8, 10, 12, 8, 8, 11, 13, 1, 1, 3, 6, 1, 1, 3, 6, 2, 2, 4, 8, 2, 2, 7, 9, 1, 1, 3, 6, 1, 1, 3, 6, 2, 2, 4, 8, 2, 2, 7, 9, 6, 6, 8, 9, 6, 6, 8, 9, 7, 7, 10, 11, 7, 7, 12, 13, 6, 6, 8, 9, 6, 6, 8, 9, 9, 9, 11, 13, 9, 9, 13, 14 }; static const char rotationHash[] = { 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 3, 3, 2, 2, 3, 3, 2, 2, 3, 3, 3, 3, 3, 3, 3, 3, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 0, 0, 2, 2, 0, 0, 2, 2, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 3, 3, 1, 1, 3, 3, 2, 2, 3, 3, 2, 2, 0, 3, 1, 1, 3, 3, 1, 1, 3, 3, 2, 2, 1, 2, 2, 2, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 2, 2, 1, 1, 2, 2, 3, 3, 0, 0, 3, 3, 0, 0, 1, 1, 3, 3, 1, 1, 3, 3, 2, 2, 2, 2, 2, 2, 3, 3, 1, 1, 3, 3, 1, 1, 3, 3, 2, 2, 1, 2, 2, 2, 1, 3 }; //build current hash unsigned char hash = 0; hash = (hash << 1) | (board->getTileOrBorder(x-1, y)==tile); hash = (hash << 1) | (board->getTileOrBorder(x-1, y-1)==tile); hash = (hash << 1) | (board->getTileOrBorder(x, y-1)==tile); hash = (hash << 1) | (board->getTileOrBorder(x+1, y-1)==tile ); hash = (hash << 1) | (board->getTileOrBorder(x+1, y)==tile); hash = (hash << 1) | (board->getTileOrBorder(x+1, y+1)==tile); hash = (hash << 1) | (board->getTileOrBorder(x, y+1)==tile); hash = (hash << 1) | (board->getTileOrBorder(x-1, y+1)==tile); slot = tileHash[ hash ]; rotation = rotationHash[ hash ];
Then the slot is used to index a texture atlas, and the rotation is used to rotate texture UVs (it is rendered with polygons on a terrain). Ifs: 0 Number of unique tiles needed for a single terrain type: a mere 14 Awesome: 10 How much I recommend to try this at home: 0
|