2015-06-30 50 views
1

我试图生成一个大的瓷砖地图,然后将显示在屏幕上。地图应该是随机的,目前只包含两种类型的贴图。在Python中用于平面贴图for循环的问题

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

我相信这是由于我写了我的循环,它遍历整个高度图,甚至在达到第二个贴图列表之前。虽然由于我的尝试包含了一些随机元素,所以应该至少有一些噪声引入到地图中,但似乎没有任何元素。

这里是一个链接,显示当我运行我的代码时显示的内容。

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 

http://i.stack.imgur.com/zboQK.png

回答

0

你写了很多像行:

if height == range(1, 3): 

但是这不符合你的想法。

range(1, 3)返回列表[1, 2](或产生12如果你使用python3可迭代),这是永远不会等于一个整数。


你可能想使用一种模式,如:

if height == 1 or height == 2 

if 1 <= height <= 2: 

if height in range(1, 2): 

Nonethe少,你可以通过创建一个返回草砖的一个给定的高度的机会一个辅助函数简化代码:

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 
+0

太感谢你了,让我知道我错在哪里,然后无论如何给我一个更有效的解决方案!我遇到的一个后续问题是chance_of_grass是否是Python代码的首选样式? 也就是说,在编写python方法时,我应该使用下划线还是camelcase(chanceOfGrass)? – PKJamoo

+0

@PKJamoo在python中,你通常使用下划线作为函数。从python样式指南:*函数名称应该是小写字母,必要时用下划线分隔以提高可读性。 – sloth

0
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