• API
• FAQ
• Tools
• Trends
• Archive
daily pastebin goal
43%
SHARE
TWEET

# Map generator and editor (python, pygame)

billysback May 1st, 2014 205 Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
1. import sys, pygame, math, random
2.
3. from pygame.locals import *
4. pygame.init()
5.
6. #random_seed = 238572983412674123
7. #random.seed(random_seed)
8.
9. #people, houses
10.
11.
12. hmap = []
13. for i in range(100):
14.     hmap.append(0)
15.
16. br, bcr = [0, 42], [ [0, 0, 100], [0, 0, 255] ] #water colour range for height map
17. sr, scr = [42, 45], [ [255, 204, 51], [255, 225, 80] ] #sand colour range for height map
18. gr, gcr = [45, 55], [ [0, 240, 0], [0, 200, 0] ] #grass colour range for height map
19. tr, tcr = [55, 64], [ [0, 160, 0], [0, 100, 0] ] #tree colour range for height map
20. rr, rcr = [64, 100], [ [150,150,150], [255, 255, 255] ] #mountain/rock/snow colour range for height map
21.
22. rs = [ [br, bcr], [sr, scr], [gr, gcr], [tr, tcr], [rr, rcr] ]
23.
24. for i in range(100):
25.     for j in range(len(rs)):
26.         r, c = rs[j][0], rs[j][1]
27.         if i >= r[0] and i < r[1]:
28.             c1, c2 = c[0], c[1]
29.             per = ( (i-r[0])/(r[1]-r[0]) )
30.             rgb = [ c1[0] + ( (c2[0]-c1[0]) * per),
31.                     c1[1] + ( (c2[1]-c1[1]) * per),
32.                     c1[2] + ( (c2[2]-c1[2]) * per) ]
33.             hmap[i] = rgb
34.
35. width, height = 300, 300
36. scale = 3
37. maps = [1, 1]
38.
39. dimensions = (width*scale*maps[0], height*scale*maps[1])
40.
41. screen = pygame.display.set_mode(dimensions)
42.
43. mapImg = pygame.Surface(dimensions)
44. overlay = pygame.Surface(dimensions).convert_alpha()
45. overlay.fill( (0,0,0,0) )
46.
47. sky = pygame.Surface((width*scale, height*scale)).convert_alpha()
48. sky.fill( (0,0,0,0) )
49.
50. def drawScreen():
51.     screen.blit(mapImg, (0, 0))
52.     screen.blit(overlay, (0, 0))
53.     screen.blit(sky, (0, 0))
54.     pygame.display.flip()
55.
56. def isValid(x, y):
57.     if x >= 0 and x < width*maps[0] and y >= 0 and y < height*maps[1]:
58.         return True
59.     return False
60.
61. bordersOn = True
62. border = [0, 0, 0]
63. borderDiff = 0
64. def drawPixel(target, x, y, col, borders, lighting):
65.     xf, yf = x*scale, y*scale
66.     xt, yt = (x*scale)+scale, (y*scale)+scale
67.
68.     for rx in range(xf, xt):
69.         for ry in range(yf, yt):
70.             tcol = col
71.             border = [col[0]-100, col[1]-100, col[2]-100]
72.             if bordersOn and (col[0] > 0 or col[1] > 0):
73.                 if (rx == xf and borders[3]): #West (Left)
74.                     tcol = border
75.                 elif (rx == xt-1 and borders[1]): #East (Right)
76.                     tcol = border
77.                 elif (ry == yf and borders[0]): #North (Up)
78.                     tcol = border
79.                 elif (ry == yt-1 and borders[2]): #South (Down)
80.                     tcol = border
81.
82.             for i in range(len(tcol)):
83.                 if tcol[i] > 255:
84.                     tcol[i] = 255
85.                 elif tcol[i] < 0:
86.                     tcol[i] = 0
87.
88.             target.set_at((rx, ry), tcol)
89.
90. def getBorders(x, y, rdiff):
91.     borders = [False, False, False, False] #North, East, South, West
92.     if isValid(x, y):
93.         h = wmap[x][y][0]
94.         col = hmap[h]
95.
96.         for o in range(-1, 2, 2):
97.             ps = [ [x+o, y], [x, y+o] ]
98.             for i in range(len(ps)):
99.                 p = ps[i]
100.
101.                 if isValid(p[0], p[1]):
102.
103.                     col2 = hmap[wmap[p[0]][p[1]][0]]
104.                     diff = math.fabs(col[0]-col2[0]) + math.fabs(col[1]-col2[1]) + math.fabs(col[2]-col2[2])
105.                     if diff > rdiff and bordersOn:
106.                         if p[0] < x: #West
107.                             borders[3] = False
108.                         elif p[0] > x: #East
109.                             borders[1] = True
110.                         elif p[1] < y: #North
111.                             borders[0] = False
112.                         elif p[1] > y: #South
113.                             borders[2] = True
114.     return borders
115.
116. wmap = []
117.
118. for x in range(width*maps[0]):
119.     tab = []
120.     for y in range(height*maps[1]):
121.         h = random.randint(0,99)
122.
123.         tab.append([h, 0])
124.     wmap.append(tab)
125.
126. def getDist(x1, y1, x2, y2):
127.     return math.sqrt( ((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)) )
128.
129. smooth = 3
130. sharp = 1
131. def smoothmapImg():
132.     for x in range(width*scale):
133.         for y in range(height*scale):
134.             col = mapImg.get_at((x, y))
135.             col = [col[0]*sharp, col[1]*sharp, col[2]*sharp]
136.             n = sharp
137.             for ox in range(-smooth, smooth+1):
138.                 for oy in range(-smooth, smooth+1):
139.                     if (x+ox) >= 0 and (x+ox) < width*scale and (y+oy) >= 0 and (y+oy) < height*scale:
140.                         tempc = mapImg.get_at((x+ox, y+oy))
141.                         col = [col[0] + tempc[0], col[1]+tempc[1], col[2]+tempc[2] ]
142.                         n = n + 1
143.             col[0] = math.floor(col[0]/n)
144.             col[1] = math.floor(col[1]/n)
145.             col[2] = math.floor(col[2]/n)
146.             mapImg.set_at((x, y), col)
147.
148.
149. def drawWorld(surface, offsetx, offsety):
150.     for x in range(width*maps[0]):
151.         for y in range(height*maps[1]):
152.             h = wmap[x][y][0]
153.             col = hmap[h]
154.
155.             lighting = wmap[x][y][1]
156.
157.             drawPixel(surface, x, y, col, getBorders(x, y, borderDiff), lighting)
158.     drawScreen()
159.
160.
161. def drawArea(surface, fpos, tpos):
162.     for x in range(fpos[0], tpos[0]+1):
163.         for y in range(fpos[1], tpos[1]+1):
164.             h = wmap[x][y][0]
165.             col = hmap[h]
166.
167.             lighting = wmap[x][y][1]
168.
169.             drawPixel(surface, x, y, col, getBorders(x, y, borderDiff), lighting)
170.     drawScreen()
171.
172. def addHotspot(x, y, h, intensity, dist):
173.     for ox in range(-dist, dist+1):
174.         for oy in range(-dist, dist+1):
175.             if (ox*ox)+(oy*oy) <= dist*dist and isValid(x+ox, y+oy):
176.                 per = 100- ((( (ox*ox) + (oy*oy) )/(dist*dist))*100)
177.                 i = math.ceil( (intensity/100)*per )
178.                 wmap[x+ox][y+oy].append([h, i])
179.
180. drange = [30, 70]
181. def generateHotspot(x, y):
182.     #print("Hotspot position: ",x,",",y)
183.     pos = [x, y]
184.     h = random.randint(0, 99)
185.     intensity = random.randint(6, 13)
186.     dist = random.randint(drange[0], drange[1])
187.     addHotspot(pos[0], pos[1], h, intensity, dist)
188.
189. def genHotspots(offsetx, offsety):
190.     avgdrange = (drange[0]+drange[1])/2
191.     hotspot_amt = math.ceil( (width*height)/(math.pi*avgdrange*avgdrange) )
192.     hotroot = math.ceil(math.sqrt(hotspot_amt))
193.     wpart, hpart = width/hotroot, height/hotroot
194.     hotroot = hotroot*2
195.     for x in range(0, hotroot):
196.
197.         for y in range(0, hotroot):
198.             rx = ( (x*wpart) + wpart )/2
199.             ry = ( (y*hpart) + hpart)/2
200.             offset = [random.randint(0, math.floor(wpart))-(wpart/2), random.randint(0, math.floor(hpart))-(hpart/2)]
201.             generateHotspot(math.floor(rx+offset[0])+offsetx, math.floor(ry+offset[1])+offsety)
202.
203.     print(hotspot_amt, ", ", hotroot)
204.
205.
206. def getAverageHeight(x, y, sens, hotspots, circular):
207.     nlist = []
208.     total = 0
209.     n = 0
210.     if isValid(x, y) and hotspots == True:
211.         if len(wmap[x][y]) > 2:
212.             for i in range(2, len(wmap[x][y])):
213.                 hotspot = wmap[x][y][i]
214.                 total = total + (hotspot[0]*hotspot[1])
215.                 n = n + hotspot[1]
216.     for ox in range(-sens, sens+1):
217.         for oy in range(-sens, sens+1):
218.             if isValid(x+ox, y+oy):
219.                 if circular:
220.                     if getDist(x, y, x+ox, y+oy) <= sens:
221.                         total = total + wmap[x+ox][y+oy][0]
222.                         n = n + 1
223.                 else:
224.                     total = total + wmap[x+ox][y+oy][0]
225.                     n = n + 1
226.     h = 0
227.     if n != 0:
228.         h = math.floor(total/n)
229.         if h > 99:
230.             h = 99
231.     return h
232.
233.
234.
235. def smoothWorld(offset, amt, sens, hotspots):
236.     todo = []
237.     for x in range(width*amt[0]):
238.         for y in range(height*amt[1]):
239.             wmap[x+offset[0]][y+offset[1]][0] = getAverageHeight(x+offset[0], y+offset[1], sens, hotspots, False)
240.
241. def smoothArea(offset, fpos, tpos, sens, hotspots, circ):
242.     for x in range(fpos[0], tpos[0]+1):
243.         for y in range(fpos[1], tpos[1]+1):
244.             if isValid(x, y):
245.                 wmap[x+offset[0]][y+offset[1]][0] = getAverageHeight(x+offset[0], y+offset[1], sens, hotspots, circ)
246.
247. def getTotalAverageHeight():
248.     total = 0
249.     n = 0
250.     for x in range(width):
251.         for y in range(height):
252.             total = total + wmap[x][y][0]
253.             n = n + 1
254.
255.     return math.floor(total/n)
256.
257. def createWorld(surface, offsetx, offsety):
258.     genHotspots(offsetx, offsety)
259.     #drawWorld(surface, offsetx, offsety)
260.
261.     print("Smoothing world, pass 1")
262.     smoothWorld([offsetx, offsety], [1,1], 2, True)
263.     #drawWorld(surface, offsetx, offsety)
264.
265.     print("Smoothing world, pass 2")
266.     smoothWorld([offsetx, offsety], [1,1], 2, False)
267.     #drawWorld(surface, offsetx, offsety)
268.
269.     print("Smoothing world, pass 3")
270.     smoothWorld([offsetx, offsety], [1,1], 3, True)
271.     #drawWorld(surface, offsetx, offsety)
272.
273.     print("Smoothing world, pass 4")
274.     smoothWorld([offsetx, offsety], [1,1], 4, False)
275.     #drawWorld(surface, offsetx, offsety)
276.
277. createWorld(mapImg, 0, 0)
278. drawWorld(mapImg, 0, 0)
279. #createWorld(mapImg, width, 0)
280. #createWorld(mapImg, width, height)
281. #createWorld(mapImg, 0, height)
282.
283. def joinWorlds():
284.     print("Smoothing all maps, pass 1")
285.     smoothWorld([0,0], maps, 4, True)
286.     drawWorld(mapImg, 0, 0)
287.
288.     print("Smoothing all maps, pass 2")
289.     smoothWorld([0,0], maps, 3, False)
290.     drawWorld(mapImg, 0, 0)
291.
292. #joinWorlds()
293. print("Done!")
294. print("Finding village locations...")
295.
296. villageHouses = 7
297. villageSize = 40
298. houseSize = 2
299. def findVillageLocations(size):
300.     locations = []
301.     for x in range(width):
302.         for y in range(height):
303.             h = wmap[x][y][0]
304.             if h >= gr[0] and h < gr[1]:
305.                 ah = getAverageHeight(x, y, size, False, True)
306.                 if ah >= h-2 and ah <= h+2:
307.                     canCreate = True
308.                     for i in range(len(locations)):
309.                         if getDist(locations[i][0], locations[i][1], x, y) < size*2:
310.                             canCreate = False
311.                     if canCreate:
312.                         locations.append([x, y])
313.     return locations
314.
315. class House:
316.     def __init__(self, village, x, y, size):
317.         self.village = village
318.         self.x = x
319.         self.y = y
320.         self.size = size
321.
322.     def draw(self):
323.         for ox in range(-self.size, self.size+1):
324.             for oy in range(-self.size, self.size+1):
325.                 if getDist(self.x, self.y, self.x+ox, self.y+oy) <= self.size:
326.                     drawPixel(overlay, self.x+ox, self.y+oy, [140, 123, 55, 255], [True, True, False, False], 0)
327.
328. class Village:
329.     def __init__(self, loc, size, hamt, hsize):
330.         houses = []
331.         n = 0
332.         while len(houses) < hamt and n < 50:
333.             pos = [random.randint(loc[0]-size, loc[0]+size), random.randint(loc[1]-size, loc[1]+size)]
334.             dist = getDist(loc[0], loc[1], pos[0], pos[1])
335.             if dist <= size and isValid(pos[0], pos[1]):
336.                 canCreate = True
337.                 for i in range(len(houses)):
338.                     house = houses[i]
339.                     if getDist(pos[0], pos[1], house.x, house.y) < hsize*2:
340.                         canCreate = False
341.                 ph = wmap[pos[0]][pos[1]][0]
342.                 if canCreate and ph >= gr[0] and ph < gr[1]:
343.                     houses.append(House(self, pos[0], pos[1], hsize))
344.             n = n + 1
345.         self.houses = houses
346.         self.x = loc[0]
347.         self.y = loc[1]
348.         self.size = size
349.
350.     def draw(self):
351.         for i in range(len(self.houses)):
352.             self.houses[i].draw()
353.
354.
355.
356. #locs = findVillageLocations(villageSize)
357.
358. #print("Creating villages... (",len(locs),")")
359. #villages = []
360. #for i in range(len(locs)):
361. #    v = Village(locs[i], villageSize, villageHouses, houseSize)
362. #    v.draw()
363. #    villages.append(v)
364.
365. print("Done!")
366. drawScreen()
367.
368. curSens = 2
369. def getTilePosition(pos):
370.     return [math.floor(pos[0]/scale), math.floor(pos[1]/scale)]
371.
372. def raiseArea(amt, fpos, tpos, circ):
373.     centre = [(fpos[0]+tpos[0])/2, (fpos[1]+tpos[1])/2]
374.     for x in range(fpos[0], tpos[0]+1):
375.         for y in range(fpos[1], tpos[1]+1):
376.             if isValid(x, y):
377.                 if (circ != 0 and getDist(x, y, centre[0], centre[1]) <= circ) or (circ == 0):
378.                     wmap[x][y][0] = wmap[x][y][0] + amt
379.                     if wmap[x][y][0] > 99:
380.                         wmap[x][y][0] = 99
381.                     if wmap[x][y][0] < 0:
382.                         wmap[x][y][0] = 0
383.
384. mouseMode = 0
385. # 0 = smooth
386. # 1 = raise
387. # 2 = lower
389. # 4 = hotspot_remove
390. mouseHotspots = False
391. mouseCirc = True
392. mouseArea = 2
393.
394. mouseHeight = 49
395. mouseIntensity = 7
396.
397. scrollMode = 0
398. # 0 = brush size
399. # 1 = sensitivity
400. # 2 = height
401. # 3 = intensity
402.
403. mticks = pygame.time.get_ticks()
404. kticks = pygame.time.get_ticks()
405. while 1:
406.     for event in pygame.event.get():
407.         if event.type == QUIT:
408.             sys.exit()
409.         if event.type == pygame.MOUSEBUTTONDOWN:
410.             if event.button == 4: #scroll up
411.                 if scrollMode == 0:
412.                     mouseArea = mouseArea + 1
413.                     print("Brush size: ", mouseArea)
414.                 elif scrollMode == 1:
415.                     curSens = curSens + 1
416.                     print("Cursor sensitivity: ", curSens)
417.                 elif scrollMode == 2:
418.                     mouseHeight = mouseHeight + 1
419.                     print("Mouse height (hotspot): ", mouseHeight)
420.                 elif scrollMode == 3:
421.                     mouseIntensity = mouseIntensity + 1
422.                     print("Mouse intensity (hotspot): ", mouseIntensity)
423.             elif event.button == 5: #scroll down
424.                 if scrollMode == 0:
425.                     mouseArea = mouseArea - 1
426.                     if mouseArea < 0:
427.                         mouseArea = 0
428.                     print("Brush size: ", mouseArea)
429.                 elif scrollMode == 1:
430.                     curSens = curSens - 1
431.                     if curSens < 0:
432.                         curSens = 0
433.                     print("Cursor sensitivity: ", curSens)
434.                 elif scrollMode == 2:
435.                     mouseHeight = mouseHeight - 1
436.                     if mouseHeight < 0:
437.                         mouseHeight = 0
438.                     print("Mouse height (hotspot): ", mouseHeight)
439.                 elif scrollMode == 3:
440.                     mouseIntensity = mouseIntensity - 1
441.                     if mouseIntensity < 0:
442.                         mouseIntensity = 0
443.                     print("Mouse intensity (hotspot): ", mouseIntensity)
444.
445.     if pygame.time.get_ticks() - kticks >= 100:
446.         keys = pygame.key.get_pressed()
447.         if keys[pygame.K_1]:
448.             mouseMode = 0
449.             print("Mouse set to smooth")
450.         elif keys[pygame.K_2]:
451.             mouseMode = 1
452.             print("Mouse set to raise")
453.         elif keys[pygame.K_3]:
454.             mouseMose = 2
455.             print("Mouse set to lower")
456.         elif keys[pygame.K_4]:
457.             mouseMode = 3
458.             print("Mouse mode set to hotspot! (one use)")
459.         if keys[pygame.K_q]:
460.             mouseHotspots = (mouseHotspots == False)
461.             print("Smoothing hotspots set to ", str(mouseHotspots))
462.         if keys[pygame.K_w]:
463.             mouseCirc = (mouseCirc == False)
464.             print("Circular brush set to ", str(mouseCirc))
465.         if keys[pygame.K_a]:
466.             scrollMode = 0
467.             print("Scroll mode set to brush size")
468.         elif keys[pygame.K_s]:
469.             scrollMode = 1
470.             print("Scroll mode set to sensitivity")
471.         elif keys[pygame.K_d]:
472.             scrollMode = 2
473.             print("Scroll mode set to height (hotspot)")
474.         elif keys[pygame.K_f]:
475.             scrollMode = 3
476.             print("Scroll mode set to intensity")
477.         if keys[pygame.K_z]:
478.             print("Smoothing world...")
479.             smoothWorld([0,0], maps, curSens, mouseHotspots)
480.             print("Drawing world...")
481.             drawWorld(mapImg, 0, 0)
482.             print("Done!")
483.
484.         kticks = pygame.time.get_ticks()
485.
486.     if pygame.time.get_ticks() - mticks >= 50:
487.         prsd = pygame.mouse.get_pressed()
488.         if prsd[2] or prsd[0]:
489.             if mouseMode == 0:
490.                 #print("SMOOTHING_TILE")
491.                 pos = getTilePosition(pygame.mouse.get_pos())
492.                 #offset, fpos, tpos, sens, hostpots, circular
493.                 smoothArea([0,0], [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea], curSens, mouseHotspots, mouseCirc)
494.                 #surface, fpos, tpos
495.                 drawArea(mapImg, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea])
496.             elif mouseMode == 1:
497.                 pos = getTilePosition(pygame.mouse.get_pos())
498.                 circ = 0
499.                 if mouseCirc:
500.                     circ = curSens
501.                 raiseArea(1, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea], circ)
502.                 drawArea(mapImg, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea])
503.             elif mouseMode == 2:
504.                 pos = getTilePosition(pygame.mouse.get_pos())
505.                 circ = 0
506.                 if mouseCirc:
507.                     circ = curSens
508.                 raiseArea(-1, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea], circ)
509.                 drawArea(mapImg, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea])
510.             elif mouseMode == 3: #hotspot
511.                 #addHotspot(x, y, h, intensity, dist)
512.                 pos = getTilePosition(pygame.mouse.get_pos())
513.                 addHotspot(pos[0], pos[1], mouseHeight, mouseIntensity, mouseArea)
514.                 mouseMode = 0
515.
516.
517.         mticks = pygame.time.get_ticks()
RAW Paste Data
Top