Skip to content

Instantly share code, notes, and snippets.

@austindoeswork
Forked from TylerLeite/creature_generate.py
Last active December 2, 2016 20:11
Show Gist options
  • Save austindoeswork/fc681a186624ddfda7d55b93278e1006 to your computer and use it in GitHub Desktop.
Save austindoeswork/fc681a186624ddfda7d55b93278e1006 to your computer and use it in GitHub Desktop.
Create a random creature
from PIL import Image, ImageFilter
import os
import sys
import random
import math
def main():
if len(sys.argv) <= 1:
print "USAGE: python spritegen.py <image/dir>"
return;
walk_dir = sys.argv[1]
width = 100
height = 100
x_buf = 8 # empty buffer around image
y_buf = 8
num_colors = 10
for i in range(50):
print i
filepath = walk_dir + "/" + str(i) + ".png"
matrix = genMatrix(width,height,x_buf,y_buf,num_colors)
saveImage(filepath,matrix,width,height,x_buf,y_buf,num_colors)
def genMatrix(width, height, x_buf, y_buf, num_colors):
# typeMatrix holds the type of pixel
# >= 0 color
# -2 face
# -1 empty
type_matrix = [[-1 for x in range(width)] for y in range(height)]
# while the sprite doesn't suck
while True:
# seed the matrix with some random pixels
for x in range(x_buf, width - x_buf):
for y in range(y_buf, height - y_buf):
if random.randint(0, 100) < 20:
type_matrix[x][y] = random.randrange(num_colors)
# grow the seeds
for generation in range(4):
tmp = [[-1 for x in range(height)] for y in range(height)]
for x in range(1, width - 1):
for y in range(1, height - 1):
count = 0
for i in range(-1, 2):
for j in range(-1, 2):
if type_matrix[x+i][y+j] != -1:
count += 1
# rules for growing
if type_matrix[x][y] == -1:
if count > 4 or count == 0:
tmp[x][y] = random.randrange(num_colors)
elif type_matrix[x][y] != -1:
if count < 4 or count == 0:
tmp[x][y] = -1
# put back into type matrix
type_matrix = [[tmp[x][y] for x in range(width)] for y in range(height)]
# re-colorize the pixels based on surrounding colors
for generation in range(2):
for x in range(1, width - 1):
for y in range(1, height - 1):
if type_matrix[x][y] == -1:
continue
else:
counts = [0] * num_colors
for i in range(-1, 2):
for j in range(-1, 2):
color = type_matrix[x+i][y+j]
if color == -1:
continue
else:
counts[color] += 1
color = counts.index(max(counts))
if color == type_matrix[x][y]:
for i in range(-1, 2):
for j in range(-1, 2):
if type_matrix[x+i][y+j] == -1:
continue
if random.randrange(100) < 40:
type_matrix[x+i][y+j] = color
else:
if random.randrange(100) < 10:
type_matrix[x][y] = color
#notshitty.club
out = False
for x in range(x_buf + 2, width - (x_buf + 2)):
if out:
break
for y in range(x_buf + 2, width - (x_buf + 2)):
if out:
break
count = 0
#best way to find block for face
for i in range(-2, 4):
for j in range(-2, 4):
if type_matrix[x+i][y+j] != -1:
count += 1
if count == 36:
plop_face(type_matrix, x, y)
out = True
count = 0
if out:
break
type_matrix = [[-1 for x in range(width)] for y in range(height)]
# print "trying again"
# pprint(type_matrix)
return type_matrix
# x,y is top left of 3x3 face
def plop_face(input_matrix, x, y):
face_type = random.randrange(6)
# no mouth
if face_type == 0:
face = [[1,0,1],
[0,0,0],
[0,0,0]]
# cyclopz
elif face_type == 1:
face = [[0,1,0],
[0,0,0],
[1,1,1]]
# default
else:
face = [[1,0,1],
[0,0,0],
[1,1,1]]
# set face
for i in range(3):
for j in range(3):
if face[j][i] == 1:
input_matrix[x+i][y+j] = -2
# get_colors returns (colors[num_colors],face_color)
def get_colors(num_colors):
face_color = (0,0,0,255)
#color schemes
light_scheme = [0,32,64,96]
light_face = (0,0,0,255)
dark_scheme = [128,160,192,224]
black_face = (255,255,255,255)
colors = []
#light
if random.randrange(2) == 0:
for i in range(num_colors):
r = random.choice(light_scheme)
g = random.choice(light_scheme)
b = random.choice(light_face)
colors.append((r,g,b,255))
face_color = black_face
#dark
else:
for i in range(num_colors):
r = random.choice(dark_scheme)
g = random.choice(dark_scheme)
b = random.choice(dark_scheme)
colors.append((r,g,b,255))
return colors, face_color
# save matrix as PNG
def saveImage(filepath, input_matrix, width, height, x_buf, y_buf, num_colors):
img = Image.new("RGBA", (width,height), 0)
imgMatrix = img.load()
colors, face_color = get_colors(num_colors)
for x in range(width):
for y in range(height):
out = (0,0,0,0)
if x >= x_buf and x <= width-x_buf and y >= y_buf and y <= height-y_buf:
if input_matrix[x][y] >= 0:
out = colors[input_matrix[x][y]]
elif input_matrix[x][y] == -2:
out = face_color
imgMatrix[x,y] = out
img.save(filepath, "PNG")
# =============================================================================
# HELPERS
# =============================================================================
#shoutout http://stackoverflow.com/users/989121/georg
def pprint(matrix):
s = [[str(e) for e in row] for row in matrix]
lens = [max(map(len, col)) for col in zip(*s)]
fmt = ' '.join('{{:{}}}'.format(x) for x in lens)
table = [fmt.format(*row) for row in s]
print '\n'.join(table)
if __name__ == "__main__":
main()
<html>
<head>
<style>
#img {
image-rendering: pixelated;
width: 320px;
height: 320px;
}
</style>
<script>
var pic = 0;
var nextfn = function() {
pic++;
document.getElementById("img").src = "output/" + pic + ".png";
};
var prevfn = function() {
if (pic === 0) return;
pic--;
document.getElementById("img").src = "output/" + pic + ".png";
};
</script>
</head>
<body>
<img id="img" src="cell/0.png">
<button onclick="prevfn();">PREV</button>
<button onclick="nextfn();">NEXT</button>
</body>
</html>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment