-
-
Save austindoeswork/fc681a186624ddfda7d55b93278e1006 to your computer and use it in GitHub Desktop.
Create a random creature
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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() |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<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