Skip to content

Commit

Permalink
Sanify terrain images, remove 'random' from tile.
Browse files Browse the repository at this point in the history
Tile array now stores Surface references rather than list indexes.
All sprites are now selected at load time, makes things much tidier.
  • Loading branch information
Francis Herne committed Dec 17, 2014
1 parent 21998ae commit 0b269cb
Show file tree
Hide file tree
Showing 3 changed files with 40 additions and 64 deletions.
32 changes: 17 additions & 15 deletions Map.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,28 +53,30 @@ def __init__(self, mapdict):
for i in [(1,1,1), (1,0,2), (-1,1,4), (-1,0,8)]:
nbrcount += (groundarray == numpy.roll(groundarray, i[0], axis=i[1])) * i[2]

randomgrid = numpy.random.randint(256, size=self.size)
self.cellarray = numpy.empty(self.size, dtype=terrain.celldtype)
for color_type in terrain.color_typeindex(groundimage):
istype = groundarray == color_type[0]
self.cellarray[istype] = terrain.typeindextocell[color_type[1]]
for level in ['groundimage', 'topimage']:
indexmap = terrain.typetoimageindex[level][color_type[1]]
dirsetlist = filter(lambda a: isinstance(a, list), indexmap)
if dirsetlist:
images = terrain.typeindextocell[color_type[1]][level]
if not images:
continue
nbrimagelists = filter(lambda a: isinstance(a, list), images)
if nbrimagelists:
# Non-directional sprites are ignored if one or more directional sets provided.
firstindexlist = [m[0] for m in dirsetlist]
randomgrid = numpy.random.randint(len(dirsetlist), size=self.size)
self.cellarray[level][istype] = (numpy.choose(randomgrid, firstindexlist) + nbrcount)[istype]
zimages = zip(*nbrimagelists)
for i in range(16):
ind = (nbrcount == i) & istype
self.cellarray[level][ind] = numpy.choose(randomgrid[ind], zimages[i], mode='wrap')
else:
randomgrid = numpy.random.randint(len(indexmap), size=self.size)
self.cellarray[level][istype] = numpy.choose(randomgrid, indexmap)[istype]
self.cellarray[level][istype] = numpy.choose(randomgrid[istype], images, mode='wrap')

for color_collectable in collectables.mapcolor.iteritems():
color = pygame.surfarray.map_array(collectablesimage, numpy.array([color_collectable[0]]))
self.cellarray['collectableitem'][collectablesarray == color] = color_collectable[1]

self.origcoins = (self.cellarray['collectableitem'] == collectables.COIN).sum()
self.cellarray['random'] = numpy.random.randint(256, size=self.size)

def __getitem__(self, coord):
"""Get map item with [], wrapping"""
Expand All @@ -98,12 +100,12 @@ def addsprite(image, layer):
def pickrandomsprite(spritelist):
return spritelist[cell['random']%len(spritelist)]

offsetsprite = images.indexedterrain[cell['groundimage']]
if offsetsprite[1]:
addsprite(offsetsprite[1], offsetsprite[0]-10)
offsetsprite = images.indexedterrain[cell['topimage']]
if offsetsprite[1]:
addsprite(offsetsprite[1], offsetsprite[0]+10)
offsetsprite = cell['groundimage']
if offsetsprite:
addsprite(offsetsprite, cell['layeroffset']-10)
offsetsprite = cell['topimage']
if offsetsprite:
addsprite(offsetsprite, cell['layeroffset']+10)

if cell['damaged']:
addsprite(pickrandomsprite(images.Damaged), -3)
Expand Down
49 changes: 9 additions & 40 deletions images.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
import os
import pygame
import collectables
import terrain
from colors import MAGENTA
from directions import *

Expand Down Expand Up @@ -66,48 +65,18 @@ def subdirs(dirpath):
"""Paths to subdirectories of 'dirpath'"""
return filter(os.path.isdir, [os.path.join(dirpath, name) for name in os.listdir(dirpath)])

terraingroups = {}
# Create list of sprites and/or of 16-sprite direction lists for each subdirectory of tiles/terrain.
terrain = {'': []}
# Create list of images or neighbour-dependent-image groups for each subdirectory of tiles/terrain.
for terraindir in subdirs(os.path.join('tiles', 'terrain')):
name = os.path.basename(terraindir)
if not (name in terrain.types['groundimage'] or name in terrain.types['topimage']):
print "Warning: terrain sprites %s not used" %name
terraingroups[name] = []
dirname = os.path.basename(terraindir)
terrain[dirname] = []
images = getimages(terraindir, colorkey=MAGENTA)
for image in images:
numtiles = float(image.get_width())/image.get_height()
if numtiles not in [1, 6]:
print "Warning: sprite has invalid size"
continue
sprite = dirsprites(image) if numtiles == 6 else image
terraingroups[name].append(sprite)

# Create list of all sprites used, in format (layeroffset, surface).
# Create list of sprite indices and/or of 16-index direction lists of indices...
# ...for each tile type in each of terrain.indexmaps['groundimage'] and ...['topimage'].
numtypes = len(terrain.types)
indexedterrain = [(0, None)]
for level in ['groundimage', 'topimage']:
for i in enumerate(terrain.types[level]):
levelmap = terrain.typetoimageindex[level]
levelmap.append([])
if not i[1]:
levelmap[i[0]].append(0)
continue
group = terraingroups[i[1]]
offset = numtypes/2 - i[0]
directionlists = []
directionlists = filter(lambda a: isinstance(a, list), group)
othersprites = filter(lambda a: not isinstance(a, list), group)
for sprite in othersprites:
index = len(indexedterrain)
indexedterrain.append((offset, sprite))
levelmap[i[0]].append(index)
for dirlist in directionlists:
index = len(indexedterrain)
indexedterrain += [(offset, sprite) for sprite in dirlist]
levelmap[i[0]].append(range(index, index+16))

ratio = image.get_width() / image.get_height()
if ratio == 1:
terrain[dirname].append(image)
elif ratio == 6:
terrain[dirname].append(dirsprites(image))

# Images with transparency use convert_alpha().

Expand Down
23 changes: 14 additions & 9 deletions terrain.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import numpy
import pygame.surfarray

import images

celltypefields = [
('name', (numpy.str_, 19)),
('top', numpy.bool_),
Expand Down Expand Up @@ -36,26 +38,29 @@ def colorlist(surface):
def color_typeindex(surface):
return zip(colorlist(surface), range(len(typeslist)))

typetoimageindex = {
'groundimage': [],
'topimage' : []
}
typeimages = []
for type in types:
typeimages.append((
images.terrain[type['groundimage']],
images.terrain[type['topimage']]
))

cellstatefields = [
('damaged', numpy.bool_),
('explored', numpy.bool_),
('collectableitem', numpy.int8),
('random', numpy.uint8)
('collectableitem', numpy.int8)
]

cellimagefields = [
('groundimage', numpy.uint8),
('topimage', numpy.uint8)
('layeroffset', numpy.int_),
('groundimage', numpy.object),
('topimage', numpy.object)
]

celldtype = numpy.dtype(cellstatefields + celltypefields + cellimagefields)

def copyfill(i):
colorlen = len(csvcolorfields)
return (0,)*len(cellstatefields) + i[1][colorlen:colorlen+len(celltypefields)] + (i[0],0)
layeroffset = (len(types)/2-i[0],)
return (0,)*len(cellstatefields) + i[1][colorlen:colorlen+len(celltypefields)] + layeroffset + typeimages[i[0]]
typeindextocell = numpy.array([copyfill(i) for i in enumerate(typeslist)], dtype=celldtype)

0 comments on commit 0b269cb

Please sign in to comment.