I've made a simple program to automate the creation of "edge tiles" for tile-based games. You know how two surfaces represented with repeating tiles, eg. sand and grass, have ugly abrupt transitions unless you carefully make a bunch of transition pieces? This program helps by loading two solid tiles plus a "mask" image, then combining them into a surface you can then save. The program supports greyscale masks, letting you do blurry, wavy transitions. To try it, draw a half-black, half-white tile with some waviness and/or grey, and use that as a mask.
Kris
""" Tile Maker Builds "edge tiles," 2D graphical tiles representing areas where two types of ground/floor material intersect. Building these manually can be a pain, so this program automates much of the process. HOW IT WORKS: The program loads two tiles representing solid terrain (eg. "the almighty grass tile" and an anonymous patch of sand), plus a "mask" tile consisting of either black and white or greyscale. Then the two tiles are combined, using the mask as a guide to which color dominates at each pixel. Want a coastline? Draw a wavy greyscale tile and sic this program on your solid terrains. Want an abrupt transition? Just use black and white. You can use different masks depending on whether you want smooth fading and/or a straight edge, and for different sizes of tile. LIMITATIONS: You need to actually draw mask images, making sure that they'll line up for a smooth transition. But you can use the same mask for many tiles if you want, which reduces the labor involved. Having said that, using just the minimum number of masks leads to repetitive- looking graphics. So depending on your game, you may want to make several masks and make several versions of each transition. SUGGESTED USE: Don't actually include this code in your game; just run it to build graphics and then put them into your existing tile system. """ __author__ = "Kris Schnee" __version__ = "2007.9.23" __license__ = "Public Domain" import pygame screen = pygame.display.set_mode((512,512)) def MakeEdgeTile(tile1,tile2,mask): t1 = tile1 t2 = tile2 if type(tile1) is str: t1 = pygame.image.load(tile1).convert() if type(tile2) is str: t2 = pygame.image.load(tile2).convert() if type(mask) is str: mask = pygame.image.load(mask).convert() canvas = pygame.surface.Surface(t1.get_size()) for y in range(t1.get_height()): for x in range(t1.get_width()): c = mask.get_at((x,y))[2] if c == 255: canvas.set_at((x,y),t2.get_at((x,y))) elif c == 0: canvas.set_at((x,y),t1.get_at((x,y))) else: color1 = t1.get_at((x,y)) color2 = t2.get_at((x,y)) p1 = 1.0 - (.00392 * c) p2 = 1.0 - p1 mixed = (color1[0]*p1 + color2[0]*p2, color1[1]*p1 + color2[1]*p2, color1[2]*p1 + color2[2]*p2) canvas.set_at((x,y),mixed) return canvas def GrabTileFromTileset(tileset,tile_xy,tile_size=(128,128)): """Return a section clipped from a tileset image.""" tile = pygame.surface.Surface(tile_size) tile.blit(tileset,(0,0),(tile_xy[0]*tile_size[0],tile_xy[1]*tile_size[1],tile_size[0],tile_size[1])) return tile def DrawTile(tile,tile_xy): """Display a tile, to demonstrate this program.""" size = tile.get_size() screen.blit(tile,(tile_xy[0]*size[0],tile_xy[1]*size[1])) def RunDemo(): """This demo assumes you've got some tile images and a mask handy.""" tile1 = "grass.png" tile2 = "sand.png" maskname = "mask.png" sample = MakeEdgeTile(tile1,tile2,maskname) screen.blit(sample,(0,0)) pygame.display.update()