简体   繁体   中英

Python Matrix of Objects - Defining Attributes

I have created a matrix of objects using the following code:

class Tiles:

    def __init__(self, char="", blocked=False):
        self.char = char
        self.blocked = blocked

row = [Tiles()] * grid_width
matrix = [list(row) for i in range(grid_height)]

I then render the list contents using Pygame's render method as below:

for i, row in enumerate(matrix):
    for j, tile in enumerate(row):
        text = game_font.render(Tiles().char, True, [255, 255, 255])
        text_rect = text.get_rect()
        text_rect.center = (j * TILESIZE + (TILESIZE // 2), i * TILESIZE + (TILESIZE // 2))
        screen.blit(text, text_rect)

I would like to define the.char attribute for all indexes that require a difference character to the default. I am unsure how to do this.

So, how would I go about changing the character of individual indices at will and, also, is this the best logical approach?

I recommend to crate a dictionary , which associates a character to an index tuple:

charmap = {(0, 1) : 'A', (2, 5) : 'B', (3, 4) : 'C'}

The above map associates A to the row 0 and column 1, B to the row 2 and column 5 and C to the row 3 and column 4.

A character can be get from the location (i, j) by .get() where the 1st parameter is the key and the 2nd parameter is the default value. Get a character at an arbitrary location (i, j) and else "" by:

c = charmap.get((i, j), "")

Use this to generate the matrix:

matrix = [[Tiles(charmap.get((i, j), "")) 
          for j in range(grid_width)] for i in range(grid_height)]

Alternatively you can predefine tiles for certain positions:

tilemap = {(0, 1) : Tiles('A'), (2, 5) : Tiles('B'), (3, 4) : Tiles('C')}
matrix = [[tilemap.get((i, j), Tiles())
          for j in range(grid_width)] for i in range(grid_height)]

In both case you can render the tiles by 2 nested loops, but note in the loop you've to access the Tiles object form the matrix by tile.char . Tiles().char would create an entire new object:

for i, row in enumerate(matrix):
  for j, tile in enumerate(row):
      text = game_font.render(tile.char, True, [255, 255, 255])
      text_rect = text.get_rect()
      text_rect.center = (j * TILESIZE + (TILESIZE // 2), i * TILESIZE + (TILESIZE // 2))
      screen.blit(text, text_rect)

To simplify things, I recommend to add a draw mehtod to the class Tiles . This makes this makes it easier to handle additional attributes like a color:

class Tiles:

    def __init__(self, char="", color=(255, 255, 255), blocked=False):
        self.char = char
        self.color = color
        self.blocked = blocked

    def draw(self):
        text = game_font.render(self.char, True, self.color)
        text_rect = text.get_rect()
        text_rect.center = (j * TILESIZE + (TILESIZE // 2), i * TILESIZE + (TILESIZE // 2))
        screen.blit(text, text_rect)

Specif the individual tiles:

tilemap = {
    (0, 1) : Tiles('A', (255, 0, 0)),
    (2, 5) : Tiles('B', (0, 255, 0)),
    (3, 4) : Tiles('C', (0, 0, 255))}

matrix = [[tilemap.get((i, j), Tiles())
          for j in range(grid_width)] for i in range(grid_height)]

Call the draw method in the nested loops:

for i, row in enumerate(matrix):
    for j, tile in enumerate(row):
        tile.draw()

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM