""" Terrain generation experiments (1) Public domain. Based on an academic paper: Realtime Procedural Terrain Generation Realtime Synthesis of Eroded Fractal Terrain for Use in Computer Games Jacob Olsen, xenorg@imada.sdu.dk Department of Mathematics And Computer Science (IMADA) University of Southern Denmark October 31, 2004 This is a quick and dirty implementation of some of the "Voronoi" algorithm mentioned in the above paper, for terrain generation. This code was done by Kris Schnee late one night and should not be blamed on the authors. """ import pygame pygame.init() import random random.seed("Next My Generation") ## Song title I was listening to screen = pygame.display.set_mode((512,512)) #### Here's one way of generating some random static. ##t_random = pygame.surface.Surface((256,256)) ##t_random.fill((0,0,0)) ##for y in range(0,256): ## for x in range(0,256): ## c = random.randint(0,128)+random.randint(0,64)+random.randint(0,32)+random.randint(0,16)+random.randint(0,8) ## t_random.set_at((x,y),(c,c,c)) ## ##for r in range(5): ## for y in range(1,255): ## for x in range(1,255): ## n = (t_random.get_at((x,y-1))[0]+t_random.get_at((x,y+1))[0]+ ## t_random.get_at((x-1,y))[0]+t_random.get_at((x+1,y))[0])/4 ## ## h = t_random.get_at((x,y))[0] ## if n > h+16: ## h += 16 ## t_random.set_at((x,y),(h,h,h)) ## elif n < h-16: ## h -= 16 ## t_random.set_at((x,y),(h,h,h)) ##t_random = pygame.transform.scale2x(t_random) ##pygame.image.save(t_random,"smoothed_static.bmp") ## Once you generate this using the above code, just use this line: ##t_random = pygame.image.load("smoothed_static.bmp").convert() #### This chunk of code doesn't do what it's supposed to, #### but the effect is cool. A fractal? ##import pygame ##pygame.init() ##import random ##random.seed("Next My Generation") ##screen = pygame.display.set_mode((512,512)) ## ##voronoi = pygame.surface.Surface((500,500)) ##voronoi.fill((0,0,0)) ##for zy in range(0,512,100): ## for zx in range(0,512,100): ## f1 = (random.randint(zx,zx+0),random.randint(zy,zy+0)) ## for y in range(zy,zy+99): ## for x in range(zx,zx+99): ## dist_approx = pow(zx-x,2) + pow(zy-y,2) ## h = dist_approx ## voronoi.set_at((x,y),h) ## Try multiplying h by a power of 2! ## ##screen.blit(voronoi,(0,0)) ##pygame.display.update() #### Another neat glitch effect, kind of like brushed steel. ##t_voronoi = pygame.surface.Surface((512,512)) ##t_voronoi.fill((0,0,0)) ##for zy in range(0,512,128): ## for zx in range(0,512,128): ## f1x,f1y = (random.randint(zx,zx+127),random.randint(zy,zy+127)) ## f2x,f2y = (random.randint(zx,zx+127),random.randint(zy,zy+127)) ## for y in range(zy,zy+128): ## for x in range(zx,zx+128): ## dist_approx_1 = pow(f1x-x,2) + pow(f1y-y,2) ## h1 = int((dist_approx_1 / 32768.0) * 256) ## dist_approx_2 = pow(f2x-x,2) + pow(f2y-y,2) ## h2 = 1 / (int((dist_approx_2 / 32768.0) * 256)+1) ## c = h1-(h2/2) ## t_voronoi.set_at((x,y),(c,c,c)) t_voronoi = pygame.surface.Surface((513,513)) t_voronoi.fill((0,0,0)) feature_points = [] for zy in range(0,512,128): for zx in range(0,512,128): f1x,f1y = (random.randint(zx,zx+127),random.randint(zy,zy+127)) feature_points.append((f1x,f1y)) ## f2x,f2y = (random.randint(zx,zx+127),random.randint(zy,zy+127)) for y in range(0,512): for x in range(0,512): closest = 99999 for point in feature_points: dist_approx_1 = pow(point[0]-x,2) + pow(point[1]-y,2) if dist_approx_1 < closest: closest = dist_approx_1 ## Base the height on the distance to the nearest feature point. ## I don't have this part down in an ideal way. ## This line version doesn't work. ## h1 = int((1-(closest/262144.0)) * 256)-1 ## This version gives little circles. ## h1 = [0,255][closest < 100] ## This version gives dark bubbles on white. ## h1 = (closest/10000.0)*256 ## White bubbles on black. h1 = (1-(closest/5000.0))*256 ## Fuzzy; reminds me of some cheese I left in the fridge too long. ## h1 = (1-(float(closest)/random.randint(3000,40000)))*256 h1 = max(min(h1,255),0) c = h1 t_voronoi.set_at((x,y),(c,c,c)) ## Render the Voronoi terrain. terrain = t_voronoi screen.blit(terrain,(0,0)) #### Alternative: Blend it with some random static. ##t_voronoi.set_alpha(200) ##t_random.blit(t_voronoi,(0,0)) ##terrain = t_random ##screen.blit(terrain,(0,0)) pygame.display.update()