为 Pygame 中的纹理瓷砖、墙壁和出口组合单独的关卡贴图
Combining Seperate Level Maps For texture Tiles, Walls & Exits in Pygame
我正在尝试将 2 个单独的列表变成一个图块地图。
- 用于放置色块或纹理
- 是用来放置墙壁**和出口点。
我使用两种不同的方法来创建图块,使用字符来表示图块。我可以让这两种方法分别工作,但想结合使用它们吗?
理想情况下,我希望知道如何将来自 2 个列表、
的两个结果结合起来
#map of the colors or textured tiles
level1tile = ["------",
"-$$---",
"-$^^$-",
"------"
]
#level1tile is a simple mapping: char -> colour
colors = {'X': pygame.color.THECOLORS['blue'],
'-': pygame.color.THECOLORS['grey'],
'^': pygame.color.THECOLORS['brown'] ]
}
#map of the walls and level exits
level1wall = ["WWWWWW",
"W E",
"W WW W",
"WWWWWW"
]
#level1wall is collision detection W = wall, E = exit, P = Player
- 用于放置色块或纹理
- 是用来放置墙壁**和出口点。
我将添加不可见的项目,所以我想保留两个单独的地图,这样一些标题可以具有与墙相同或不同的纹理。
一些可能的用途示例:
1.你可以穿过一些水砖,但不能穿过其他的
2.流沙、隐形物品或陷阱
所以在第一张地图中用 X 蓝色表示 水砖
colors = {'X': pygame.color.THECOLORS['blue']}
在第二个中我代表了water with W for the wall collision detection.
在这个例子中,我通过使用 W 作为墙壁来进行碰撞检测来阻挡区域,蓝色或水和灰色或岩石瓷砖是玩家无法行走的区域。
在这个例子中,我通过使用 W 作为墙壁来进行碰撞检测来阻挡区域,蓝色或水和灰色或岩石瓷砖是玩家无法行走的区域。但我想保留两张地图,以防我想添加不可见区域或一些你可以行走的水等。
level = ["WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W WWWWWWWWW WW EW",
"W WWWWWWW W",
"W WW WWW W",
"W WW WWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WW W",
"W W",
"W W W",
"W WWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWWW W",
"W WWW W",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"]
# W = wall, E = exit, P = Player
x = y = 0
for row in level:
for col in row:
if col == "W":
Wall((x, y))
if col == "E":
end_rect = pygame.Rect(x, y, 32, 32)
x += 32
y += 32
x = 0
我正在使用一种技术来创建颜色或纹理平铺贴图,这是我在阅读会员 Sloth 的帖子时学到的。
levelB = ["------------------------------------",
"- $$$$$$$$$--------- -- $ $ $ $E-",
"- $ $$$$$$$$-------^^^^ $$-",
"-$ $$$$$$$$ -- ^^^^ XXX $-",
"- $$$$$$$ -- $ ^^^^ XXXXX -",
"- $$$$$$$ ^^^^ XXXXXXX -",
"- $$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$$ ^^^^ XXXXXXX -",
"-$$$$$$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$ ^^^^ XX -",
"- $ $$$ ^^^^ $ $ $ $ -",
"- $$$$$$ ^^^^- $$$$$$$$-",
"- $$$$$$ ^^^^--- $$$$$ $ $ -",
"- $$$$$ ^^^^----- $$$$$$$-",
"- $$$$$$$ ^^^^----- $ $ $ $ -",
"- $$$$$$$ ^^^^----- $$$$$$ $$-",
"- $$$$$$ ^^^^ ------ $ $ $ $ -",
"- $$$$$$$$ ^^^^ --- $$-",
"------------------------------------"]
#a simple mapping: char -> colour
colors = {'X': pygame.color.THECOLORS['blue'],
'-': pygame.color.THECOLORS['grey'],
'$': pygame.color.THECOLORS['green'],
'^': pygame.color.THECOLORS['brown'],
'E': pygame.color.THECOLORS['black']
}
blocksize = 32
我将用纹理贴图交换颜色
#######################################
下面是我根据提供的答案进行的尝试,但我只得到了一半的检查。
完整来源
import os
import random
import pygame
#map of the colors or textured tiles
level1tile = ["------------------------------------",
"- $$$$$$$$$--------- -- $ $ $ $E-",
"- $ $$$$$$$$-------^^^^ $$-",
"-$ $$$$$$$$ -- ^^^^ XXX $-",
"- $$$$$$$ -- $ ^^^^ XXXXX -",
"- $$$$$$$ ^^^^ XXXXXXX -",
"- $$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$$ ^^^^ XXXXXXX -",
"-$$$$$$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$ ^^^^ XX -",
"- $ $$$ ^^^^ $ $ $ $ -",
"- $$$$$$ ^^^^- $$$$$$$$-",
"- $$$$$$ ^^^^--- $$$$$ $ $ -",
"- $$$$$ ^^^^----- $$$$$$$-",
"- $$$$$$$ ^^^^----- $ $ $ $ -",
"- $$$$$$$ ^^^^----- $$$$$$ $$-",
"- $$$$$$ ^^^^ ------ $ $ $ $ -",
"- $$$$$$$$ ^^^^ --- $$-",
"------------------------------------"]
#a simple mapping: char -> color
colors = {'X': pygame.color.THECOLORS['blue'],
'-': pygame.color.THECOLORS['grey'],
'$': pygame.color.THECOLORS['green'],
'^': pygame.color.THECOLORS['brown'],
'E': pygame.color.THECOLORS['black']
}
blocksize = 32
#map of the walls and level exits
level1wall = ["WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W WWWWWWWWW WW EW",
"W WWWWWWW W",
"W WW WWW W",
"W WW WWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WW W",
"W W",
"W W W",
"W WWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWWW W",
"W WWW W",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"]
# Class for the Player object
class Player(object):
def __init__(self):
self.rect = pygame.Rect(32, 32, 16, 16)
def move(self, dx, dy):
# Move each axis separately. Note that this checks for collisions both times.
if dx != 0:
self.move_single_axis(dx, 0)
if dy != 0:
self.move_single_axis(0, dy)
def move_single_axis(self, dx, dy):
# Move the rect
self.rect.x += dx
self.rect.y += dy
# If you collide with a wall, move out based on velocity
for wall in walls:
if self.rect.colliderect(wall.rect):
if dx > 0: # collide right
self.rect.right = wall.rect.left
if dx < 0: # collide left
self.rect.left = wall.rect.right
if dy > 0: # collide top
self.rect.bottom = wall.rect.top
if dy < 0: # collide bottom
self.rect.top = wall.rect.bottom
# Nice class to hold a wall rect
class Wall(object):
def __init__(self, pos):
walls.append(self)
self.rect = pygame.Rect(pos[0], pos[1], 32, 32)
#level1wall is collision detection W = wall, E = exit, P = Player
#Block
class Block(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block, and its x and y position
def __init__(self, color, width, height, x, y):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
# Update the position of this object by setting the values of rect.x and rect.y
self.rect = self.image.get_rect(top=y, left=x)
pygame.init()
# Set up the display
pygame.display.set_caption("Tiles and Walls!")
screen = pygame.display.set_mode((len(level[0])* blocksize, len(level*blocksize)))
#screen = pygame.display.set_mode((1150, 600))
clock = pygame.time.Clock()
walls = [] # List to hold the walls
player = Player() # Create the player
combined_list = [] # initialize a blank list
for i in range(len(level1tile)): # build your new list
combined_list.append(zip(level1tile[i], level1wall[i]))
# Parse the level string above. W = wall, E = exit
x = y = 0
for row in level1wall:
for col in row:
if col == "W":
Wall((x, y))
if col == "E":
end_rect = pygame.Rect(x, y, 32, 32)
x += 32
y += 32
x = 0
running = True
while running:
clock.tick(60)
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
running = False
# Move the player if an arrow key is pressed
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
player.move(-2, 0)
if key[pygame.K_RIGHT]:
player.move(2, 0)
if key[pygame.K_UP]:
player.move(0, -2)
if key[pygame.K_DOWN]:
player.move(0, 2)
# Just added this to make it slightly fun ;)
if player.rect.colliderect(end_rect):
raise SystemExit("Next Level!")
# Draw the scene
screen.fill((0, 0, 0))
for wall in walls:
pygame.draw.rect(screen, (255, 255, 255), wall.rect)
pygame.draw.rect(screen, (255, 0, 0), end_rect)
pygame.draw.rect(screen, (255, 200, 0), player.rect)
pygame.display.flip()
没有 Itertools
我可能会推荐使用 Python 中的 zip()
函数。基本上它需要两个(或更多)列表作为参数和 returns 一个列表,其中每个元素是原始两个列表在该位置的值的元组。例如,您可以创建一个新列表,其中在地图中的每个位置都有一个元组 (tile, wall)
:
combined_list = [] # initialize a blank list
for i in range(len(level1tile)): # build your new list
combined_list.append(zip(level1tile[i], level1wall[i]))
在你的问题中使用你的第一个例子,returns:
combined_list =
[[('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W')],
[('-', 'W'), ('$', ' '), ('$', ' '), ('-', ' '), ('-', ' '), ('-', 'E')],
[('-', 'W'), ('$', ' '), ('^', 'W'), ('^', 'W'), ('$', ' '), ('-', 'W')],
[('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W')]]
然后您可以获取地图中任何给定位置的瓷砖和墙壁状态,(x, y)
,类似于:
(tile, wall) = combined_list[x][y]
然后您可以分别访问 tile
和 wall
:
>> (tile, wall) = combined_list[1][0]
>> tile
'-'
>> wall
'W'
是否符合您要查找的内容?
可能有一种非常聪明的方法可以将这两个字符串列表与列表推导结合起来,但我无法完全让它为我工作。
编辑:使用 Itertools
是用 itertools
做到这一点的巧妙方法!好吧,有点。我不能完全保留你的 2D 布局,而是设法将所有 (tile, wall)
元组放入一个 1 x n*m
-length 列表(而不是 n x m
2D 列表) :
import itertools as it
combined = list(it.izip(it.chain.from_iterable(level1tile), it.chain.from_iterable(level2tile)))
现在您可以访问 (x, y)
位置的 (tile, wall)
值:
(tile, wall) = combined[x + y*n] # where "n" is how many columns you have in your map
可能 仍然 有更优雅的方法来使用 itertools
(或不使用),但希望这会有所帮助。
由于您使用字符来表示瓷砖和墙壁,因此您可以将它们连接成一个字符串以合并两个列表。组合列表将需要更少的内存,以这种方式提供比将它们放入列表或字符元组所需的更快的访问。
之后,您可以分别使用 combined[row][col][0]
和 combined[row][col][1]
直接访问特定位置的瓷砖和墙壁字符。
使用 itertools.izip()
而不是 zip()
可以减少内存消耗,因为它不需要创建临时中间列表。使用 xrange()
而不是 range()
也是如此。
try:
from itertools import izip
except ImportError: # Python3
izip = zip
xrange = range
combined = [tuple(tile+wall for tile, wall in zip(level1tile[i], level1wall[i]))
for i in xrange(len(level1tile))]
from pprint import pprint
print('level1tile and level1wall combined:')
pprint(combined)
print('')
print('combined[1][5] -> {!r}'.format(combined[1][5]))
tile, wall = combined[1][5]
print('after "tile, wall = combined[1][5]:"')
print(' tile, wall -> {!r},{!r}'.format(tile, wall))
输出:
level1tile and level1wall combined:
[('-W', '-W', '-W', '-W', '-W', '-W'),
('-W', '$ ', '$ ', '- ', '- ', '-E'),
('-W', '$ ', '^W', '^W', '$ ', '-W'),
('-W', '-W', '-W', '-W', '-W', '-W')]
combined[1][5] -> '-E'
after "tile, wall = combined[1][5]:"
tile, wall -> '-','E'
我正在尝试将 2 个单独的列表变成一个图块地图。
- 用于放置色块或纹理
- 是用来放置墙壁**和出口点。
我使用两种不同的方法来创建图块,使用字符来表示图块。我可以让这两种方法分别工作,但想结合使用它们吗?
理想情况下,我希望知道如何将来自 2 个列表、
的两个结果结合起来#map of the colors or textured tiles
level1tile = ["------",
"-$$---",
"-$^^$-",
"------"
]
#level1tile is a simple mapping: char -> colour
colors = {'X': pygame.color.THECOLORS['blue'],
'-': pygame.color.THECOLORS['grey'],
'^': pygame.color.THECOLORS['brown'] ]
}
#map of the walls and level exits
level1wall = ["WWWWWW",
"W E",
"W WW W",
"WWWWWW"
]
#level1wall is collision detection W = wall, E = exit, P = Player
- 用于放置色块或纹理
- 是用来放置墙壁**和出口点。
我将添加不可见的项目,所以我想保留两个单独的地图,这样一些标题可以具有与墙相同或不同的纹理。
一些可能的用途示例: 1.你可以穿过一些水砖,但不能穿过其他的 2.流沙、隐形物品或陷阱
所以在第一张地图中用 X 蓝色表示 水砖
colors = {'X': pygame.color.THECOLORS['blue']}
在第二个中我代表了water with W for the wall collision detection.
在这个例子中,我通过使用 W 作为墙壁来进行碰撞检测来阻挡区域,蓝色或水和灰色或岩石瓷砖是玩家无法行走的区域。
在这个例子中,我通过使用 W 作为墙壁来进行碰撞检测来阻挡区域,蓝色或水和灰色或岩石瓷砖是玩家无法行走的区域。但我想保留两张地图,以防我想添加不可见区域或一些你可以行走的水等。
level = ["WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W WWWWWWWWW WW EW",
"W WWWWWWW W",
"W WW WWW W",
"W WW WWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WW W",
"W W",
"W W W",
"W WWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWWW W",
"W WWW W",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"]
# W = wall, E = exit, P = Player
x = y = 0
for row in level:
for col in row:
if col == "W":
Wall((x, y))
if col == "E":
end_rect = pygame.Rect(x, y, 32, 32)
x += 32
y += 32
x = 0
我正在使用一种技术来创建颜色或纹理平铺贴图,这是我在阅读会员 Sloth 的帖子时学到的。
levelB = ["------------------------------------",
"- $$$$$$$$$--------- -- $ $ $ $E-",
"- $ $$$$$$$$-------^^^^ $$-",
"-$ $$$$$$$$ -- ^^^^ XXX $-",
"- $$$$$$$ -- $ ^^^^ XXXXX -",
"- $$$$$$$ ^^^^ XXXXXXX -",
"- $$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$$ ^^^^ XXXXXXX -",
"-$$$$$$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$ ^^^^ XX -",
"- $ $$$ ^^^^ $ $ $ $ -",
"- $$$$$$ ^^^^- $$$$$$$$-",
"- $$$$$$ ^^^^--- $$$$$ $ $ -",
"- $$$$$ ^^^^----- $$$$$$$-",
"- $$$$$$$ ^^^^----- $ $ $ $ -",
"- $$$$$$$ ^^^^----- $$$$$$ $$-",
"- $$$$$$ ^^^^ ------ $ $ $ $ -",
"- $$$$$$$$ ^^^^ --- $$-",
"------------------------------------"]
#a simple mapping: char -> colour
colors = {'X': pygame.color.THECOLORS['blue'],
'-': pygame.color.THECOLORS['grey'],
'$': pygame.color.THECOLORS['green'],
'^': pygame.color.THECOLORS['brown'],
'E': pygame.color.THECOLORS['black']
}
blocksize = 32
我将用纹理贴图交换颜色
#######################################
下面是我根据提供的答案进行的尝试,但我只得到了一半的检查。
完整来源
import os
import random
import pygame
#map of the colors or textured tiles
level1tile = ["------------------------------------",
"- $$$$$$$$$--------- -- $ $ $ $E-",
"- $ $$$$$$$$-------^^^^ $$-",
"-$ $$$$$$$$ -- ^^^^ XXX $-",
"- $$$$$$$ -- $ ^^^^ XXXXX -",
"- $$$$$$$ ^^^^ XXXXXXX -",
"- $$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$$ ^^^^ XXXXXXX -",
"-$$$$$$$$$$$$$$ ^^^^ XXXXXX -",
"- $$$$$$$ ^^^^ XX -",
"- $ $$$ ^^^^ $ $ $ $ -",
"- $$$$$$ ^^^^- $$$$$$$$-",
"- $$$$$$ ^^^^--- $$$$$ $ $ -",
"- $$$$$ ^^^^----- $$$$$$$-",
"- $$$$$$$ ^^^^----- $ $ $ $ -",
"- $$$$$$$ ^^^^----- $$$$$$ $$-",
"- $$$$$$ ^^^^ ------ $ $ $ $ -",
"- $$$$$$$$ ^^^^ --- $$-",
"------------------------------------"]
#a simple mapping: char -> color
colors = {'X': pygame.color.THECOLORS['blue'],
'-': pygame.color.THECOLORS['grey'],
'$': pygame.color.THECOLORS['green'],
'^': pygame.color.THECOLORS['brown'],
'E': pygame.color.THECOLORS['black']
}
blocksize = 32
#map of the walls and level exits
level1wall = ["WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW",
"W WWWWWWWWW WW EW",
"W WWWWWWW W",
"W WW WWW W",
"W WW WWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WWWWWWW W",
"W WWWWWW W",
"W WW W",
"W W",
"W W W",
"W WWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWW W",
"W WWWWWW W",
"W WWW W",
"WWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWWW"]
# Class for the Player object
class Player(object):
def __init__(self):
self.rect = pygame.Rect(32, 32, 16, 16)
def move(self, dx, dy):
# Move each axis separately. Note that this checks for collisions both times.
if dx != 0:
self.move_single_axis(dx, 0)
if dy != 0:
self.move_single_axis(0, dy)
def move_single_axis(self, dx, dy):
# Move the rect
self.rect.x += dx
self.rect.y += dy
# If you collide with a wall, move out based on velocity
for wall in walls:
if self.rect.colliderect(wall.rect):
if dx > 0: # collide right
self.rect.right = wall.rect.left
if dx < 0: # collide left
self.rect.left = wall.rect.right
if dy > 0: # collide top
self.rect.bottom = wall.rect.top
if dy < 0: # collide bottom
self.rect.top = wall.rect.bottom
# Nice class to hold a wall rect
class Wall(object):
def __init__(self, pos):
walls.append(self)
self.rect = pygame.Rect(pos[0], pos[1], 32, 32)
#level1wall is collision detection W = wall, E = exit, P = Player
#Block
class Block(pygame.sprite.Sprite):
# Constructor. Pass in the color of the block, and its x and y position
def __init__(self, color, width, height, x, y):
# Call the parent class (Sprite) constructor
pygame.sprite.Sprite.__init__(self)
# Create an image of the block, and fill it with a color.
# This could also be an image loaded from the disk.
self.image = pygame.Surface([width, height])
self.image.fill(color)
# Fetch the rectangle object that has the dimensions of the image
# Update the position of this object by setting the values of rect.x and rect.y
self.rect = self.image.get_rect(top=y, left=x)
pygame.init()
# Set up the display
pygame.display.set_caption("Tiles and Walls!")
screen = pygame.display.set_mode((len(level[0])* blocksize, len(level*blocksize)))
#screen = pygame.display.set_mode((1150, 600))
clock = pygame.time.Clock()
walls = [] # List to hold the walls
player = Player() # Create the player
combined_list = [] # initialize a blank list
for i in range(len(level1tile)): # build your new list
combined_list.append(zip(level1tile[i], level1wall[i]))
# Parse the level string above. W = wall, E = exit
x = y = 0
for row in level1wall:
for col in row:
if col == "W":
Wall((x, y))
if col == "E":
end_rect = pygame.Rect(x, y, 32, 32)
x += 32
y += 32
x = 0
running = True
while running:
clock.tick(60)
for e in pygame.event.get():
if e.type == pygame.QUIT:
running = False
if e.type == pygame.KEYDOWN and e.key == pygame.K_ESCAPE:
running = False
# Move the player if an arrow key is pressed
key = pygame.key.get_pressed()
if key[pygame.K_LEFT]:
player.move(-2, 0)
if key[pygame.K_RIGHT]:
player.move(2, 0)
if key[pygame.K_UP]:
player.move(0, -2)
if key[pygame.K_DOWN]:
player.move(0, 2)
# Just added this to make it slightly fun ;)
if player.rect.colliderect(end_rect):
raise SystemExit("Next Level!")
# Draw the scene
screen.fill((0, 0, 0))
for wall in walls:
pygame.draw.rect(screen, (255, 255, 255), wall.rect)
pygame.draw.rect(screen, (255, 0, 0), end_rect)
pygame.draw.rect(screen, (255, 200, 0), player.rect)
pygame.display.flip()
没有 Itertools
我可能会推荐使用 Python 中的 zip()
函数。基本上它需要两个(或更多)列表作为参数和 returns 一个列表,其中每个元素是原始两个列表在该位置的值的元组。例如,您可以创建一个新列表,其中在地图中的每个位置都有一个元组 (tile, wall)
:
combined_list = [] # initialize a blank list
for i in range(len(level1tile)): # build your new list
combined_list.append(zip(level1tile[i], level1wall[i]))
在你的问题中使用你的第一个例子,returns:
combined_list =
[[('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W')],
[('-', 'W'), ('$', ' '), ('$', ' '), ('-', ' '), ('-', ' '), ('-', 'E')],
[('-', 'W'), ('$', ' '), ('^', 'W'), ('^', 'W'), ('$', ' '), ('-', 'W')],
[('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W'), ('-', 'W')]]
然后您可以获取地图中任何给定位置的瓷砖和墙壁状态,(x, y)
,类似于:
(tile, wall) = combined_list[x][y]
然后您可以分别访问 tile
和 wall
:
>> (tile, wall) = combined_list[1][0]
>> tile
'-'
>> wall
'W'
是否符合您要查找的内容?
可能有一种非常聪明的方法可以将这两个字符串列表与列表推导结合起来,但我无法完全让它为我工作。
编辑:使用 Itertools
是用 itertools
做到这一点的巧妙方法!好吧,有点。我不能完全保留你的 2D 布局,而是设法将所有 (tile, wall)
元组放入一个 1 x n*m
-length 列表(而不是 n x m
2D 列表) :
import itertools as it
combined = list(it.izip(it.chain.from_iterable(level1tile), it.chain.from_iterable(level2tile)))
现在您可以访问 (x, y)
位置的 (tile, wall)
值:
(tile, wall) = combined[x + y*n] # where "n" is how many columns you have in your map
可能 仍然 有更优雅的方法来使用 itertools
(或不使用),但希望这会有所帮助。
由于您使用字符来表示瓷砖和墙壁,因此您可以将它们连接成一个字符串以合并两个列表。组合列表将需要更少的内存,以这种方式提供比将它们放入列表或字符元组所需的更快的访问。
之后,您可以分别使用 combined[row][col][0]
和 combined[row][col][1]
直接访问特定位置的瓷砖和墙壁字符。
使用 itertools.izip()
而不是 zip()
可以减少内存消耗,因为它不需要创建临时中间列表。使用 xrange()
而不是 range()
也是如此。
try:
from itertools import izip
except ImportError: # Python3
izip = zip
xrange = range
combined = [tuple(tile+wall for tile, wall in zip(level1tile[i], level1wall[i]))
for i in xrange(len(level1tile))]
from pprint import pprint
print('level1tile and level1wall combined:')
pprint(combined)
print('')
print('combined[1][5] -> {!r}'.format(combined[1][5]))
tile, wall = combined[1][5]
print('after "tile, wall = combined[1][5]:"')
print(' tile, wall -> {!r},{!r}'.format(tile, wall))
输出:
level1tile and level1wall combined:
[('-W', '-W', '-W', '-W', '-W', '-W'),
('-W', '$ ', '$ ', '- ', '- ', '-E'),
('-W', '$ ', '^W', '^W', '$ ', '-W'),
('-W', '-W', '-W', '-W', '-W', '-W')]
combined[1][5] -> '-E'
after "tile, wall = combined[1][5]:"
tile, wall -> '-','E'