Python 中 Tile 映射的 for 循环问题

Problems with for loops for Tile Mapping in Python

我正在尝试生成一张大图块地图,然后将其显示在屏幕上。地图应该是随机的,目前只包含两种类型的图块。

但是,现在发生的情况是 Tile Map 的每一行都被高度图中的第一行覆盖,因此我的地图在显示时会显示类似瓷砖的直线列。

我相信这是由于我编写 for 循环的方式造成的,它遍历整个高度图,甚至在到达第二个图块列表之前。虽然由于我 试图 包含的瓷砖选择有些随机元素,至少应该有一些噪音引入地图,但似乎没有。

这是我 运行 我的代码时显示内容的 link 屏幕截图。

 import pygame, random



class Map(object):

    MAPWIDTH = 64
    MAPHEIGHT = 48
    HEIGHTS = [0, 1, 2, 3, 4, 5, 6, 7, 8]

    def __init__(self):
        self.heightmap = [[random.choice(self.HEIGHTS) for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
        self.Tiles = [['' for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
        for rows in self.Tiles:
            for row in self.heightmap:
                i = 0

                for height in row:
                        # 100% water block
                        if height == 0:
                            rows[i] = 'WATER'
                        # 70% water block
                        if height == range(1, 3):
                            if random.randint(0, 9) == range(0, 6):
                                rows[i] = 'WATER'
                            else:
                                rows[i] = 'GRASS'
                        # 50% water block
                        if height == 4:
                            if random.random() == 0:
                                rows[i] = 'WATER'
                            else:
                                rows[i] = 'GRASS'
                        # 80% grass block
                        if height == range(5, 7):
                            if random.randint(0, 9) == range(0, 6):
                                rows[i] = 'GRASS'
                            else:
                                rows[i] = 'WATER'
                        # 100% grass block
                        if height == 8:
                            rows[i] = 'GRASS'
                        i += 1

self.heightmap = [[random.choice(self.HEIGHTS) for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
self.Tiles = [['' for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]

我不完全确定你想用它做什么 ^ 但试试这个:

self.heightmap=[]
self.Tiles=[]
q=[]
for w in range(self.MAPWIDTH):
    for h in range(self.MAPHEIGHT): q.append(random.choice(self.HEIGHTS))
    self.heightmap.append(q)
    q=[]
for w in range(self.MAPWIDTH):
    for h in range(self.MAPHEIGHT): q.append('')
    self.Tiles.append(q)
    q=[]
for rows in self.Tiles:
    for row in self.heightmap:
        i = 0
        for height in row:
                rows.pop(i)
                # 100% water block
                if height == 0:
                    rows.insert(i,'WATER')
                # 70% water block
                if height in range(1, 3):
                    if random.randint(0, 9) in range(0, 6):
                        rows.insert(i,'WATER')
                    else:
                        rows.insert(i,'GRASS')
                # 50% water block
                if height == 4:
                    if random.random() > 0.5:
                        rows.insert(i,'WATER')
                    else:
                        rows.insert(i,'GRASS')
                # 80% grass block
                if height in range(5, 7):
                    if random.randint(0, 9) in range(0, 6):
                        rows.insert(i,'GRASS')
                    else:
                        rows.insert(i,'WATER')
                # 100% grass block
                if height == 8:
                    rows.insert(i,'GRASS')
                i += 1

你写了很多这样的行:

if height == range(1, 3):

但这并不像你想象的那样。

range(1, 3) returns 列表 [1, 2] (或者如果你使用 python3 则产生 12 的迭代器) , 那永远不会等于一个整数。


您可能想使用如下模式:

if height == 1 or height == 2

if 1 <= height <= 2:

if height in range(1, 2):

尽管如此,您可以通过创建一个辅助函数来简化您的代码,该辅助函数 returns 给定高度的草方块的几率:

def chance_of_grass(height):
    if   height == 0: return  0
    elif height <= 3: return 30
    elif height <= 4: return 50
    elif height <= 7: return 80

    return 100

并在循环中调用它:

 def __init__(self):
    self.heightmap = [[random.choice(self.HEIGHTS) for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]
    self.Tiles = [['' for w in range(self.MAPWIDTH)] for h in range(self.MAPHEIGHT)]

    r_i = 0 # index of row
    for h_row in self.heightmap:
        c_i = 0 # index of column
        for height in row:
            is_grass = change_of_grass(height) >= random.randint(1, 100)
            self.Tiles[r_i][c_i] = 'GRASS' if is_grass else 'WATER'
            c_i += 1
        r_i += 1