【问题标题】:Problems with for loops for Tile Mapping in PythonPython中Tile Mapping的for循环问题
【发布时间】:2015-06-30 01:06:09
【问题描述】:

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

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

我相信这是由于我编写 for 循环的方式,它迭代整个高度图,甚至在到达第二个图块列表之前。尽管由于我尝试包含的图块选择的随机元素,应该至少会在地图中引入一些噪声,但似乎没有。

这是我运行代码时显示的屏幕截图的链接。

 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

【问题讨论】:

    标签: python pygame tiles


    【解决方案1】:

    你写了很多行,比如:

    if height == range(1, 3):
    

    但这并不像你认为的那样。

    range(1, 3) 返回列表 [1, 2](或者如果您使用的是 python3,则返回一个产生 12 的迭代),并且它永远不等于单个整数。


    您可能希望使用如下模式:

    if height == 1 or height == 2
    

    if 1 <= height <= 2:
    

    if height in range(1, 2):
    

    尽管如此,您可以通过创建一个帮助函数来简化代码,该函数返回给定高度的草瓦的机会:

    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
    

    【讨论】:

    • 非常感谢您让我知道我错在哪里,然后给我一个更有效的解决方案!我遇到的一个后续问题是, chance_of_grass 是否是 python 代码的首选样式?也就是说,在写python方法的时候应该使用下划线还是camelcase(chanceOfGrass)?
    • @PKJamoo 在 python 中,您通常使用下划线来表示函数。来自 python 风格指南:函数名称应该是小写的,单词之间用下划线分隔以提高可读性。
    【解决方案2】:
    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
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2011-01-26
      • 2021-10-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多