Skip to content
Advertisement

Pygame advanced map editor

I want to make a level editor in pygame, and I have a simple code that does this.

game_map = 
[['0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0','0'],
['0','0','0','0','0','0','0','0','0','0','1','1','1','0','0','0','0','0','0'],

y = 0
for row in game_map:
    x = 0
    for tile in row:
        if tile == '1':
            display.blit(dirt_image, (x * TILE_SIZE, y * TILE_SIZE))
        if tile != '0':
            tile_rects.append(pygame.Rect(x * TILE_SIZE, y * TILE_SIZE, TILE_SIZE, TILE_SIZE))
        x += 1
    y += 1

If I have dozens of objects to draw on the screen, should I check them one by one example: [0 = None, 1=dirt_img, 2=grass,3=tree,4=rock], actually I can’t think of any other way but this is there an easy way to do it simpler? sorry for bad english:)

Advertisement

Answer

There are many ways to approach this. Before I begin, if you are just getting started with Python, do not let this answer intimidate you. It is totally okay for you to have an if statement for each case.

My first recommendation is to store the game_map as a list of integers so that you do not need to add all the single quotes.

game_map = [[0, 0, 0, ...]]

One approach to the problem is as you have,

def draw_empty(x, y):
  # write your code to draw here
  pass

def draw_dirt(x, y):
  pass

...
...
for tile in row:
  if tile == 0:
    draw_empty(x, y)
  elif tile == 1:
    draw_dirt(x, y)
  elif ...

We could also be a bit clever and do a dictionary lookup:

...
for tile in row
  draw_function = {
    0: draw_empty,
    1: draw_dirt,
    ...
  }[tile]
  draw_function(x, y)

And since your tile IDs are numerical starting at 0, we could get really crazy and put the functions in a list:

draw_functions = [draw_empty, draw_dirt, ...]

...

for tile in row:
  draw_function = draw_functions[tile]
  draw_function(x, y)

While this is a fun Python exercise, the more common way this is handled is with object oriented programming.

Say we have a Tile object:

class Tile:
  def __init__(self, image, x, y):
    self.image = image
    self.x = x
    self.y = y

  def draw(self):
    # draw using self.image at self.x and self.y
    disply.blit(self.image, (self.x * TILE_SIZE, self.y * TILE_SIZE))

Then we can store game_map as a list of tiles, enumerate over them, and then say tile.draw() like the following:

for tile in game_map:
  tile.draw()
User contributions licensed under: CC BY-SA
10 People found this is helpful
Advertisement