Welcome back! I’m very happy to be working on the game again, after the brief hiatus. I made a grid system, as shown below. Here’s the latest thing little app I made, the colors and text is all just there for making the tiles visible, otherwise it’d be a blank screen :
Hit the jump for code examples, and what my old broken version of the code was.
If you’ve been following, you probably know that the gridding system has been on my to-do list for quite a long time. The way I see if, having a grid system is useful for object/actor placement, since instead of referring to their location by the pixel location, I can just refer to their location on the grid, and I can let the game sort out where they are on the screen later. It’s also useful for AI (Artificial Intelligence) because the way I had the game set up before, if the player was at co-ordinate (100, 100), it meant he was at 100 pixels right from the top left corner of the game screen and 100 pixels down from the top of the game screen. By using the grid system, I can say he’s somewhere in the (10, 10) grid, assuming the cells are 10 by 10pixels.
It also cuts down on the way AI will parse the game map. Say the game is a modest 800×600 resolution, that’s still 480 000 pixels for the path finding algorithm to check out. Just by making the cells 10 by 10, I reduce that number by 10 times. I still haven’t settled on the exact grid size, but I’m leaning towards 25×25 or 50×50. Hopefully someone will share their design with me. I always like hearing from other developers anyways!
So the reason it took this long to get started is because I didn’t know how I was going to write the grid system really, and I wasn’t certain if there was a best way to write it or not. But like all things programming, you just got to try something and see if it works. Here is what I’m currently working with, and below that is the code I had first written, when I really did not know how I was going to implement it. I’ll also attach the Tile class I wrote, as well as the drawing function that I use to make the grid onscreen. Normally, I’d try to break this down as best I can in text, but I went through and added a ton of comments, so it should be pretty easy to understand what I did.
Here’s the current incarnation of the grid building code
def createGrid2():
"""makes a list of grids topleft corners, and fills em in"""
#explicitly calling the size of the game
width = 800
height = 600
cellsize = 25 #size of each cell
key_cords = [] #key cords are the topleft corner of the cell
cells = {} #dict of all the cells > coords
global tiles
tiles = [] #using this later, instead of returning. Will need to change
#Have to find the topleft corner of all the tiles in the game
#for every row in the length of the height plus one,
# with an interval of cellsize
for y in xrange(0, height+1, cellsize):
#same thing for columns
for x in xrange(0, width+1, cellsize):
#append the coord to key_cords
key_cords.append((x, y))
#for each corner/key coordinate
for corner in key_cords:
#find all coordinates inside by adding a number between 0 and cellsize
# eg +0,+1,+2...+cellsize
cell = []
for y in range(cellsize):
for x in range(cellsize):
cell.append((corner[0] + x, corner[1] + y))
#put the cell in a dict OR:
cells[corner] = cell
#or create a tile inst
tiles.append(Tile(cell, (corner[0]/cellsize, corner[1]/cellsize)))
Here’s the Tile Class
class Tile(object):
"""A single tile, or cell"""
#----------------------------------------------------------------------
def __init__(self, coords, ID, color=(0, 0, 0)):
"""take all the coords that is inside the cell, and the ID,
the top left coord """
#all the points in the grid
self.coords = coords
#the color of the tile
# values is a randomly generated list of integers between 0 and 255
self.color = random.choice(values)
#creates a PyGamerect of the tile,
# as well as certain important coords in it.
self.set_rect()
#id, how the AI will refer to this time
self.ID = ID
#the font that is used to show the ID on the screen
self.font = PG.font.SysFont('Times', 10)
#draw the cell for the first time
self.draw()
#----------------------------------------------------------------------
def set_rect(self):
"""returns the Pygame rect"""
#smallest coord is the top left
self.topLeft = min(self.coords)
#biggest is the bottom right
self.btmRight = max(self.coords)
#some math to find the other corners
self.topRight = self.btmRight[0], self.topLeft[1]
self.btLeft = self.topLeft[0], self.btmRight[1]
#as well as to find the width and height
self.w = self.topRight[0] - self.topLeft[0]
self.h = self.topRight[1] - self.btmRight[1]
#finally, creating the rect
self.rect = PG.Rect(self.topLeft, (self.w, self.h))
#----------------------------------------------------------------------
def draw(self):
"""returns a surf with a number in the middle of self"""
#creates a surface with the height and width found in self.rect()
self.surface = PG.surface.Surface((self.rect.w, abs(self.rect.h)))
#fills it in with a color, chosen on construction
self.surface.fill(self.color)
#color key is the invisible color used when blitting
# I like this one, because it's quick to type.
self.surface.set_colorkey((123, 123, 123))
#draws the ID on a surface
number = self.font.render('{}'.format(self.ID), 0, (0, 0, 0))
#blits (draws) the ID onto the top left corner of the tile
self.surface.blit(number, (0, 0))
return self.surface
Here’s the old, ugly way of building the grid
def createGrid():
""""""
width = 800
height = 600
gridsize = 50
#divides the with and height by gridside to get an interval
wByG = width / gridsize
hByG = height / gridsize
#create coords
grids = []
#group all the lines together
for h in range(height):
widths = []
#collect all the lines
for w in range(wByG):
groups = []
#find all the coords along a line
for i in range(gridsize):
x = (gridsize * w) + i
groups.append((x, h))
widths.append(groups)
grids.append(widths)
#all > line > grouping
All = []
for row in grids:
for n in xrange(len(row)):
All.append((n, row[n]))
#sort the group
All.sort()
#I'll be honest, I can't remember what I was trying to do here
grids = []
for i in range(len(All)/gridsize):
i = (gridsize * i)
group = []
for n in range(gridsize):
pts = All[n+i][1]
for pt in pts:
group.append(pt)
grids.append(group)
#pprint.pprint(grids[0])
nGrids = len(grids)
nRows = len(grids[0])
nCells = len(grids[0][0])
print 'Number of grids {}, with {} coords per row and {} coords in each row ' \
'so a total of {} cells'.format(nGrids, nRows, nCells, (nGrids * nRows * nCells))
print 'done'
#create a tile Instance with coordinate list, and the id
# of the cell that I'll refer to it by.
global tiles
tiles = []
for i in range(len(grids)):
t = Tile(grids[i], i)
tiles.append(t)
#finally, return a list of a all the tiles together.
return grids