Subscribe to GameDev.net Direct to receive the latest updates and exclusive content.
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
Posted 29 November 2012 - 07:32 PM
Posted 29 November 2012 - 08:12 PM
Edited by Khatharr, 29 November 2012 - 08:51 PM.
Posted 29 November 2012 - 10:02 PM
Posted 29 November 2012 - 10:02 PM
I Create Games to Help Tell Stories | Writing Blog
Posted 30 November 2012 - 12:51 AM
Posted 30 November 2012 - 07:26 AM
Posted 30 November 2012 - 10:56 PM
#Aule #Function for generating a world heightmap using fractal algorithms import random from bmp import * #bmp.py must exist in same directory as this script size = 0 start_Value = 0 n = 0 A = [[v]*n for x in xrange(n)] range_Mod = 1 square_Side = n H = .5 change = False normal = 0 variation = 50 start_Height = 0 def gen(N_start=8, mapName="map", H_val=.5, norm=5, vary=40, start_H=5): if N_start > 12: print "That is a very large map. Please enter a value of 11 or less." return if N_start < 2: print "Let's think a tad larger, shall we?" return global n global square_Side global start_Value global A global range_Mod global size global H global change global normal global variation global start_Height H = H_val normal = norm variation = vary start_Height = start_H range_Mod = 1 n = (2**N_start) + 1 size = n v = 0 A = [[start_Value]*n for x in xrange(n)] A[0][0] = start_Height A[0][size-1] = start_Height A[size-1][0] = start_Height A[size-1][size-1] = start_Height square_Side = n run() print_BMP(mapName) def print_BMP(name="map"): create_BMP(A, size, name) def in_Array(point): """returns True if (x, y) is within the array""" if X(point) >= n: return False elif Y(point) >= n: return False elif X(point) < 0: return False elif Y(point) < 0: return False else: return True def get(point, square_Side=size): x = X(point) y = Y(point) if x >= n: x = square_Side/2 if x < 0: x = (n-1)- (square_Side/2) if y >= n: y = square_Side/2 if y < 0: y = (n-1)- (square_Side/2) return A[x][y] def get_Simple(point): x = X(point) y = Y(point) if in_Array(point): return A[x][y] else: return False def X(point): """Retrieves X coord from point tuple""" return point[0] def Y(point): """Retrieves Y coord from point tuple.""" return point[1] def highest_Value(): """Returns the most positive value in the array.""" highest=0 for row in A: for cell in row: if cell > highest: highest = cell return highest def highest_Coordinate(): """Returns the most positive value in the array.""" highest_val = 0 highest_coord = (0, 0) for x, row in enumerate(A): for y, cell in enumerate(row): if cell > highest_val: highest_val = cell highest_coord = (x, y) return highest_coord def lowest_Value(): """Returns the most negative value in the array.""" lowest=0 for row in A: for cell in row: if cell < lowest: lowest = cell return lowest def lowest_Coordinate(): """returns tuple (x,y) of the lowest value, or False if not found.""" lowest_val = 0 lowest_coord = (0, 0) for x, row in enumerate(A): for y, cell in enumerate(row): if cell < lowest_val: lowest_val = cell lowest_coord = (x, y) return lowest_coord def get_Neighbors(current): """Returns a list with the eight neighboring coordinates of any point.""" N = (current[0], current[1]-1) NE = (current[0]+1, current[1]-1) E = (current[0]+1, current[1]) SE = (current[0]+1, current[1]+1) S = (current[0], current[1]+1) SW = (current[0]-1, current[1]+1) W = (current[0]-1, current[1]) NW = (current[0]-1, current[1]-1) nList = [N, NE, E, SE, S, SW, W, NW] return nList def get_Cardinal_Neighbors(current): """Returns a list with the eight neighboring coordinates of any point.""" N = (current[0], current[1]-1) E = (current[0]+1, current[1]) S = (current[0], current[1]+1) W = (current[0]-1, current[1]) nList = [N, E, S, W] return nList def diamond(point, square_Side): """Operates diamond step on four values around point.""" p1 = X(point), Y(point) - (square_Side/2) p2 = X(point) + (square_Side/2), Y(point) p3 = X(point), Y(point) + (square_Side/2) p4 = X(point) - (square_Side/2), Y(point) points = [p1, p2, p3, p4] for p in points: if A[X(p)][Y(p)] != start_Value: #already set continue c1 = X(p), Y(p) - (square_Side/2) c2 = X(p) + (square_Side/2), Y(p) c3 = X(p), Y(p) + (square_Side/2) c4 = X(p) - (square_Side/2), Y(p) total_Points = 4 point_Total = 0 point_Total += get(c1, square_Side) point_Total += get(c2, square_Side) point_Total += get(c3, square_Side) point_Total += get(c4, square_Side) point_Average = point_Total/total_Points point_Value = int((point_Average + \ random.normalvariate(normal, variation)*range_Mod)) A[X(p)][Y(p)] = point_Value return def square(point, square_Side): """Operates square step around point.""" if A[X(point)][Y(point)] != start_Value: print "Conflict", c1 = X(point) - (square_Side/2), Y(point) + (square_Side/2) c2 = X(point) + (square_Side/2), Y(point) + (square_Side/2) c3 = X(point) + (square_Side/2), Y(point) - (square_Side/2) c4 = X(point) - (square_Side/2), Y(point) - (square_Side/2) total_Points = 4 point_Total = 0 point_Total += get(c1) point_Total += get(c2) point_Total += get(c3) point_Total += get(c4) point_Average = point_Total/total_Points point_Value = int((point_Average + \ random.normalvariate(normal, variation)*range_Mod)) A[X(point)][Y(point)] = point_Value return def run(): """Pretty self-explanatory, dont you think?""" global square_Side global range_Mod global H global change if square_Side < 3: #recursion end case return else: if (n == square_Side): squares = 1 else: squares = n/(square_Side-1) for i in range(squares): for j in range(squares): x = square_Side/2 + ((square_Side-1)*i) y = square_Side/2 + ((square_Side-1)*j) point = x, y square(point, square_Side) for i in range(squares): for j in range(squares): x = square_Side/2 + ((square_Side-1)*i) y = square_Side/2 + ((square_Side-1)*j) point = x, y diamond(point, square_Side) #have now run one iteration. Decrement square_Side #and recalc range_Mod and keep going. if change and square_Side < ((n/8)+1): H = 0.8 change = False square_Side = (square_Side/2)+1 range_Mod = round(range_Mod * 2**-H, 2) run() def get_Max_Size(): return n def get_Section(size_X, size_Y, startX=0, startY=0): """Returns a subsection of A from the origin (0, 0) to (size_X, size_Y)""" if size_X >= n or size_Y >= n: return False sub = [[0]*size_X for x in xrange(size_Y)] for x in range(size_Y): for y in range(size_X): sub[x][y] = A[x][y] return sub if __name__ == "__main__": gen()
#Some key imports. #Struct is used to create the actual bytes. #It is super handy for this type of thing. import struct, random #Function to write a bmp file. It takes a dictionary (d) of #header values and the pixel data (bytes) and writes them #to a file. This function is called at the bottom of the code. def bmp_write(d,the_bytes, mapName): mn1 = struct.pack('<B',d['mn1']) mn2 = struct.pack('<B',d['mn2']) filesize = struct.pack('<L',d['filesize']) undef1 = struct.pack('<H',d['undef1']) undef2 = struct.pack('<H',d['undef2']) offset = struct.pack('<L',d['offset']) headerlength = struct.pack('<L',d['headerlength']) width = struct.pack('<L',d['width']) height = struct.pack('<L',d['height']) colorplanes = struct.pack('<H',d['colorplanes']) colordepth = struct.pack('<H',d['colordepth']) compression = struct.pack('<L',d['compression']) imagesize = struct.pack('<L',d['imagesize']) res_hor = struct.pack('<L',d['res_hor']) res_vert = struct.pack('<L',d['res_vert']) palette = struct.pack('<L',d['palette']) importantcolors = struct.pack('<L',d['importantcolors']) #create the outfile outfile = open(mapName + ".bmp",'wb') #write the header + the_bytes outfile.write(mn1+mn2+filesize+undef1+undef2+offset+headerlength+width+height+\ colorplanes+colordepth+compression+imagesize+res_hor+res_vert+\ palette+importantcolors+the_bytes) outfile.close() ################################### def create_BMP(height_array, size, mapName): #Here is a minimal dictionary with header values. #Of importance is the offset, headerlength, width, #height and colordepth. #Edit the width and height to your liking. #These header values are described in the bmp format spec. #You can find it on the internet. This is for a Windows #Version 3 DIB header. d = { 'mn1':66, 'mn2':77, 'filesize':0, 'undef1':0, 'undef2':0, 'offset':54, 'headerlength':40, 'width':size, 'height':size, 'colorplanes':0, 'colordepth':24, 'compression':0, 'imagesize':0, 'res_hor':0, 'res_vert':0, 'palette':0, 'importantcolors':0 } #Function to generate a random number between 0 and 255 def rand_color(): x = random.randint(0,255) return x #Build the byte array. This code takes the height #and width values from the dictionary above and #generates the pixels row by row. The row_mod and padding #stuff is necessary to ensure that the byte count for each #row is divisible by 4. This is part of the specification. the_bytes = '' for row in range(d['height']-1,-1,-1):# (BMPs are L to R from the bottom L row) for column in range(d['width']): h = height_array[row][column] if h > 255: h = 255 if h < 0: b = 255 - abs(h) g = 0 r = 0 else: b = h g = h r = h pixel = struct.pack('<BBB',b,g,r) the_bytes = the_bytes + pixel row_mod = (d['width']*d['colordepth']/8) % 4 if row_mod == 0: padding = 0 else: padding = (4 - row_mod) padbytes = '' for i in range(padding): x = struct.pack('<B',0) padbytes = padbytes + x the_bytes = the_bytes + padbytes #call the bmp_write function with the #dictionary of header values and the #bytes created above. bmp_write(d,the_bytes, mapName)
I Create Games to Help Tell Stories | Writing Blog
Posted 01 December 2012 - 04:50 PM
Guest, the last post of this topic is over 60 days old and at this point you may not reply in this topic. If you wish to continue this conversation start a new topic.
GameDev.net™, the GameDev.net logo, and GDNet™ are trademarks of GameDev.net, LLC.