import sys, pygame, math, random
from pygame.locals import *
pygame.init()
#random_seed = 238572983412674123
#random.seed(random_seed)
#people, houses
hmap = []
for i in range(100):
hmap.append(0)
br, bcr = [0, 42], [ [0, 0, 100], [0, 0, 255] ] #water colour range for height map
sr, scr = [42, 45], [ [255, 204, 51], [255, 225, 80] ] #sand colour range for height map
gr, gcr = [45, 55], [ [0, 240, 0], [0, 200, 0] ] #grass colour range for height map
tr, tcr = [55, 64], [ [0, 160, 0], [0, 100, 0] ] #tree colour range for height map
rr, rcr = [64, 100], [ [150,150,150], [255, 255, 255] ] #mountain/rock/snow colour range for height map
rs = [ [br, bcr], [sr, scr], [gr, gcr], [tr, tcr], [rr, rcr] ]
for i in range(100):
for j in range(len(rs)):
r, c = rs[j][0], rs[j][1]
if i >= r[0] and i < r[1]:
c1, c2 = c[0], c[1]
per = ( (i-r[0])/(r[1]-r[0]) )
rgb = [ c1[0] + ( (c2[0]-c1[0]) * per),
c1[1] + ( (c2[1]-c1[1]) * per),
c1[2] + ( (c2[2]-c1[2]) * per) ]
hmap[i] = rgb
width, height = 300, 300
scale = 3
maps = [1, 1]
dimensions = (width*scale*maps[0], height*scale*maps[1])
screen = pygame.display.set_mode(dimensions)
mapImg = pygame.Surface(dimensions)
overlay = pygame.Surface(dimensions).convert_alpha()
overlay.fill( (0,0,0,0) )
sky = pygame.Surface((width*scale, height*scale)).convert_alpha()
sky.fill( (0,0,0,0) )
def drawScreen():
screen.blit(mapImg, (0, 0))
screen.blit(overlay, (0, 0))
screen.blit(sky, (0, 0))
pygame.display.flip()
def isValid(x, y):
if x >= 0 and x < width*maps[0] and y >= 0 and y < height*maps[1]:
return True
return False
bordersOn = True
border = [0, 0, 0]
borderDiff = 0
def drawPixel(target, x, y, col, borders, lighting):
xf, yf = x*scale, y*scale
xt, yt = (x*scale)+scale, (y*scale)+scale
for rx in range(xf, xt):
for ry in range(yf, yt):
tcol = col
border = [col[0]-100, col[1]-100, col[2]-100]
if bordersOn and (col[0] > 0 or col[1] > 0):
if (rx == xf and borders[3]): #West (Left)
tcol = border
elif (rx == xt-1 and borders[1]): #East (Right)
tcol = border
elif (ry == yf and borders[0]): #North (Up)
tcol = border
elif (ry == yt-1 and borders[2]): #South (Down)
tcol = border
for i in range(len(tcol)):
if tcol[i] > 255:
tcol[i] = 255
elif tcol[i] < 0:
tcol[i] = 0
target.set_at((rx, ry), tcol)
def getBorders(x, y, rdiff):
borders = [False, False, False, False] #North, East, South, West
if isValid(x, y):
h = wmap[x][y][0]
col = hmap[h]
for o in range(-1, 2, 2):
ps = [ [x+o, y], [x, y+o] ]
for i in range(len(ps)):
p = ps[i]
if isValid(p[0], p[1]):
col2 = hmap[wmap[p[0]][p[1]][0]]
diff = math.fabs(col[0]-col2[0]) + math.fabs(col[1]-col2[1]) + math.fabs(col[2]-col2[2])
if diff > rdiff and bordersOn:
if p[0] < x: #West
borders[3] = False
elif p[0] > x: #East
borders[1] = True
elif p[1] < y: #North
borders[0] = False
elif p[1] > y: #South
borders[2] = True
return borders
wmap = []
for x in range(width*maps[0]):
tab = []
for y in range(height*maps[1]):
h = random.randint(0,99)
tab.append([h, 0])
wmap.append(tab)
def getDist(x1, y1, x2, y2):
return math.sqrt( ((x1-x2)*(x1-x2)) + ((y1-y2)*(y1-y2)) )
smooth = 3
sharp = 1
def smoothmapImg():
for x in range(width*scale):
for y in range(height*scale):
col = mapImg.get_at((x, y))
col = [col[0]*sharp, col[1]*sharp, col[2]*sharp]
n = sharp
for ox in range(-smooth, smooth+1):
for oy in range(-smooth, smooth+1):
if (x+ox) >= 0 and (x+ox) < width*scale and (y+oy) >= 0 and (y+oy) < height*scale:
tempc = mapImg.get_at((x+ox, y+oy))
col = [col[0] + tempc[0], col[1]+tempc[1], col[2]+tempc[2] ]
n = n + 1
col[0] = math.floor(col[0]/n)
col[1] = math.floor(col[1]/n)
col[2] = math.floor(col[2]/n)
mapImg.set_at((x, y), col)
def drawWorld(surface, offsetx, offsety):
for x in range(width*maps[0]):
for y in range(height*maps[1]):
h = wmap[x][y][0]
col = hmap[h]
lighting = wmap[x][y][1]
drawPixel(surface, x, y, col, getBorders(x, y, borderDiff), lighting)
drawScreen()
def drawArea(surface, fpos, tpos):
for x in range(fpos[0], tpos[0]+1):
for y in range(fpos[1], tpos[1]+1):
h = wmap[x][y][0]
col = hmap[h]
lighting = wmap[x][y][1]
drawPixel(surface, x, y, col, getBorders(x, y, borderDiff), lighting)
drawScreen()
def addHotspot(x, y, h, intensity, dist):
for ox in range(-dist, dist+1):
for oy in range(-dist, dist+1):
if (ox*ox)+(oy*oy) <= dist*dist and isValid(x+ox, y+oy):
per = 100- ((( (ox*ox) + (oy*oy) )/(dist*dist))*100)
i = math.ceil( (intensity/100)*per )
wmap[x+ox][y+oy].append([h, i])
drange = [30, 70]
def generateHotspot(x, y):
#print("Hotspot position: ",x,",",y)
pos = [x, y]
h = random.randint(0, 99)
intensity = random.randint(6, 13)
dist = random.randint(drange[0], drange[1])
addHotspot(pos[0], pos[1], h, intensity, dist)
def genHotspots(offsetx, offsety):
avgdrange = (drange[0]+drange[1])/2
hotspot_amt = math.ceil( (width*height)/(math.pi*avgdrange*avgdrange) )
hotroot = math.ceil(math.sqrt(hotspot_amt))
wpart, hpart = width/hotroot, height/hotroot
hotroot = hotroot*2
for x in range(0, hotroot):
for y in range(0, hotroot):
rx = ( (x*wpart) + wpart )/2
ry = ( (y*hpart) + hpart)/2
offset = [random.randint(0, math.floor(wpart))-(wpart/2), random.randint(0, math.floor(hpart))-(hpart/2)]
generateHotspot(math.floor(rx+offset[0])+offsetx, math.floor(ry+offset[1])+offsety)
print(hotspot_amt, ", ", hotroot)
def getAverageHeight(x, y, sens, hotspots, circular):
nlist = []
total = 0
n = 0
if isValid(x, y) and hotspots == True:
if len(wmap[x][y]) > 2:
for i in range(2, len(wmap[x][y])):
hotspot = wmap[x][y][i]
total = total + (hotspot[0]*hotspot[1])
n = n + hotspot[1]
for ox in range(-sens, sens+1):
for oy in range(-sens, sens+1):
if isValid(x+ox, y+oy):
if circular:
if getDist(x, y, x+ox, y+oy) <= sens:
total = total + wmap[x+ox][y+oy][0]
n = n + 1
else:
total = total + wmap[x+ox][y+oy][0]
n = n + 1
h = 0
if n != 0:
h = math.floor(total/n)
if h > 99:
h = 99
return h
def smoothWorld(offset, amt, sens, hotspots):
todo = []
for x in range(width*amt[0]):
for y in range(height*amt[1]):
wmap[x+offset[0]][y+offset[1]][0] = getAverageHeight(x+offset[0], y+offset[1], sens, hotspots, False)
def smoothArea(offset, fpos, tpos, sens, hotspots, circ):
for x in range(fpos[0], tpos[0]+1):
for y in range(fpos[1], tpos[1]+1):
if isValid(x, y):
wmap[x+offset[0]][y+offset[1]][0] = getAverageHeight(x+offset[0], y+offset[1], sens, hotspots, circ)
def getTotalAverageHeight():
total = 0
n = 0
for x in range(width):
for y in range(height):
total = total + wmap[x][y][0]
n = n + 1
return math.floor(total/n)
def createWorld(surface, offsetx, offsety):
genHotspots(offsetx, offsety)
#drawWorld(surface, offsetx, offsety)
print("Smoothing world, pass 1")
smoothWorld([offsetx, offsety], [1,1], 2, True)
#drawWorld(surface, offsetx, offsety)
print("Smoothing world, pass 2")
smoothWorld([offsetx, offsety], [1,1], 2, False)
#drawWorld(surface, offsetx, offsety)
print("Smoothing world, pass 3")
smoothWorld([offsetx, offsety], [1,1], 3, True)
#drawWorld(surface, offsetx, offsety)
print("Smoothing world, pass 4")
smoothWorld([offsetx, offsety], [1,1], 4, False)
#drawWorld(surface, offsetx, offsety)
createWorld(mapImg, 0, 0)
drawWorld(mapImg, 0, 0)
#createWorld(mapImg, width, 0)
#createWorld(mapImg, width, height)
#createWorld(mapImg, 0, height)
def joinWorlds():
print("Smoothing all maps, pass 1")
smoothWorld([0,0], maps, 4, True)
drawWorld(mapImg, 0, 0)
print("Smoothing all maps, pass 2")
smoothWorld([0,0], maps, 3, False)
drawWorld(mapImg, 0, 0)
#joinWorlds()
print("Done!")
print("Finding village locations...")
villageHouses = 7
villageSize = 40
houseSize = 2
def findVillageLocations(size):
locations = []
for x in range(width):
for y in range(height):
h = wmap[x][y][0]
if h >= gr[0] and h < gr[1]:
ah = getAverageHeight(x, y, size, False, True)
if ah >= h-2 and ah <= h+2:
canCreate = True
for i in range(len(locations)):
if getDist(locations[i][0], locations[i][1], x, y) < size*2:
canCreate = False
if canCreate:
locations.append([x, y])
return locations
class House:
def __init__(self, village, x, y, size):
self.village = village
self.x = x
self.y = y
self.size = size
def draw(self):
for ox in range(-self.size, self.size+1):
for oy in range(-self.size, self.size+1):
if getDist(self.x, self.y, self.x+ox, self.y+oy) <= self.size:
drawPixel(overlay, self.x+ox, self.y+oy, [140, 123, 55, 255], [True, True, False, False], 0)
class Village:
def __init__(self, loc, size, hamt, hsize):
houses = []
n = 0
while len(houses) < hamt and n < 50:
pos = [random.randint(loc[0]-size, loc[0]+size), random.randint(loc[1]-size, loc[1]+size)]
dist = getDist(loc[0], loc[1], pos[0], pos[1])
if dist <= size and isValid(pos[0], pos[1]):
canCreate = True
for i in range(len(houses)):
house = houses[i]
if getDist(pos[0], pos[1], house.x, house.y) < hsize*2:
canCreate = False
ph = wmap[pos[0]][pos[1]][0]
if canCreate and ph >= gr[0] and ph < gr[1]:
houses.append(House(self, pos[0], pos[1], hsize))
n = n + 1
self.houses = houses
self.x = loc[0]
self.y = loc[1]
self.size = size
def draw(self):
for i in range(len(self.houses)):
self.houses[i].draw()
#locs = findVillageLocations(villageSize)
#print("Creating villages... (",len(locs),")")
#villages = []
#for i in range(len(locs)):
# v = Village(locs[i], villageSize, villageHouses, houseSize)
# v.draw()
# villages.append(v)
print("Done!")
drawScreen()
curSens = 2
def getTilePosition(pos):
return [math.floor(pos[0]/scale), math.floor(pos[1]/scale)]
def raiseArea(amt, fpos, tpos, circ):
centre = [(fpos[0]+tpos[0])/2, (fpos[1]+tpos[1])/2]
for x in range(fpos[0], tpos[0]+1):
for y in range(fpos[1], tpos[1]+1):
if isValid(x, y):
if (circ != 0 and getDist(x, y, centre[0], centre[1]) <= circ) or (circ == 0):
wmap[x][y][0] = wmap[x][y][0] + amt
if wmap[x][y][0] > 99:
wmap[x][y][0] = 99
if wmap[x][y][0] < 0:
wmap[x][y][0] = 0
mouseMode = 0
# 0 = smooth
# 1 = raise
# 2 = lower
# 3 = hotspot_add
# 4 = hotspot_remove
mouseHotspots = False
mouseCirc = True
mouseArea = 2
mouseHeight = 49
mouseIntensity = 7
scrollMode = 0
# 0 = brush size
# 1 = sensitivity
# 2 = height
# 3 = intensity
mticks = pygame.time.get_ticks()
kticks = pygame.time.get_ticks()
while 1:
for event in pygame.event.get():
if event.type == QUIT:
sys.exit()
if event.type == pygame.MOUSEBUTTONDOWN:
if event.button == 4: #scroll up
if scrollMode == 0:
mouseArea = mouseArea + 1
print("Brush size: ", mouseArea)
elif scrollMode == 1:
curSens = curSens + 1
print("Cursor sensitivity: ", curSens)
elif scrollMode == 2:
mouseHeight = mouseHeight + 1
print("Mouse height (hotspot): ", mouseHeight)
elif scrollMode == 3:
mouseIntensity = mouseIntensity + 1
print("Mouse intensity (hotspot): ", mouseIntensity)
elif event.button == 5: #scroll down
if scrollMode == 0:
mouseArea = mouseArea - 1
if mouseArea < 0:
mouseArea = 0
print("Brush size: ", mouseArea)
elif scrollMode == 1:
curSens = curSens - 1
if curSens < 0:
curSens = 0
print("Cursor sensitivity: ", curSens)
elif scrollMode == 2:
mouseHeight = mouseHeight - 1
if mouseHeight < 0:
mouseHeight = 0
print("Mouse height (hotspot): ", mouseHeight)
elif scrollMode == 3:
mouseIntensity = mouseIntensity - 1
if mouseIntensity < 0:
mouseIntensity = 0
print("Mouse intensity (hotspot): ", mouseIntensity)
if pygame.time.get_ticks() - kticks >= 100:
keys = pygame.key.get_pressed()
if keys[pygame.K_1]:
mouseMode = 0
print("Mouse set to smooth")
elif keys[pygame.K_2]:
mouseMode = 1
print("Mouse set to raise")
elif keys[pygame.K_3]:
mouseMose = 2
print("Mouse set to lower")
elif keys[pygame.K_4]:
mouseMode = 3
print("Mouse mode set to hotspot! (one use)")
if keys[pygame.K_q]:
mouseHotspots = (mouseHotspots == False)
print("Smoothing hotspots set to ", str(mouseHotspots))
if keys[pygame.K_w]:
mouseCirc = (mouseCirc == False)
print("Circular brush set to ", str(mouseCirc))
if keys[pygame.K_a]:
scrollMode = 0
print("Scroll mode set to brush size")
elif keys[pygame.K_s]:
scrollMode = 1
print("Scroll mode set to sensitivity")
elif keys[pygame.K_d]:
scrollMode = 2
print("Scroll mode set to height (hotspot)")
elif keys[pygame.K_f]:
scrollMode = 3
print("Scroll mode set to intensity")
if keys[pygame.K_z]:
print("Smoothing world...")
smoothWorld([0,0], maps, curSens, mouseHotspots)
print("Drawing world...")
drawWorld(mapImg, 0, 0)
print("Done!")
kticks = pygame.time.get_ticks()
if pygame.time.get_ticks() - mticks >= 50:
prsd = pygame.mouse.get_pressed()
if prsd[2] or prsd[0]:
if mouseMode == 0:
#print("SMOOTHING_TILE")
pos = getTilePosition(pygame.mouse.get_pos())
#offset, fpos, tpos, sens, hostpots, circular
smoothArea([0,0], [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea], curSens, mouseHotspots, mouseCirc)
#surface, fpos, tpos
drawArea(mapImg, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea])
elif mouseMode == 1:
pos = getTilePosition(pygame.mouse.get_pos())
circ = 0
if mouseCirc:
circ = curSens
raiseArea(1, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea], circ)
drawArea(mapImg, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea])
elif mouseMode == 2:
pos = getTilePosition(pygame.mouse.get_pos())
circ = 0
if mouseCirc:
circ = curSens
raiseArea(-1, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea], circ)
drawArea(mapImg, [pos[0]-mouseArea, pos[1]-mouseArea], [pos[0]+mouseArea, pos[1]+mouseArea])
elif mouseMode == 3: #hotspot
#addHotspot(x, y, h, intensity, dist)
pos = getTilePosition(pygame.mouse.get_pos())
addHotspot(pos[0], pos[1], mouseHeight, mouseIntensity, mouseArea)
mouseMode = 0
mticks = pygame.time.get_ticks()