Wrote a Tile system!

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
Tagged , , , , , . Bookmark the permalink.

Leave a Reply

Your email address will not be published.

You may use these HTML tags and attributes: <a href="" title=""> <abbr title=""> <acronym title=""> <b> <blockquote cite=""> <cite> <code> <del datetime=""> <em> <i> <q cite=""> <strike> <strong>