尝试以 python 更快地渲染 ASCII 艺术

Trying to render ASCII art in python faster

我正在尝试在 python

中构建基于文本的开放世界游戏
world = [["=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","=","="],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
     [" "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "," "],
    ]

for i in world:
    for j in i:
        print(j, end="")
    print("")

此代码成功打印了世界地图,尽管有点慢。有没有办法提高性能?最终我想要一张巨大的地图,玩家可以在其中移动,与敌人、NPC 等互动。有什么方法可以加快渲染速度以达到优于 .1 FPS 的速度?

我在 Python 3.7 IDLE。

谢谢!

使用 .join() 快速组合列表。

print('\n'.join([''.join(row) for row in world]))

在 IDLE 上,print 有很多开销。您可能希望在打印字符串之前对其进行编译以获得最佳性能。

如果你在 linux / osx,你可以查看 curses。使用库,您可以单独绘制像素,而不是一直重新绘制每个像素。

大地图时:只绘制当前可见的部分。

String 在 python 中已经是只读迭代器。所以你可以做类似

的事情
world = [
    "  X  ",
    " XXX ",
    " X   ",
    ]
for row in world:
    print(row)

但是您真的应该尽量减少对 print 的更多调用,这 很慢 。也许你可以只使用一个三重引号字符串?

world = """\
  X  
 XXX 
  X   """

print(world)

这样的字符串,您可以通过计算它前面的字符数来访问 (i,j) 元素。每行有 board_width + 1 个字符(不要忘记计算换行符),并且在元素 (i,j) 之前有 j 行。另外,在 0 处建立索引,您有 i 个元素与 (i,j) 在同一行,但在 (i,j) 的左侧,因此 (i,j) 元素是 world[(row_width + 1) * j + i].

如果您想保留双数组,因为它 可变 ,请考虑在打印之前将其合并为一个字符串。为此,使用 map 在一次调用中合并每一行。

displayedWorld = "\n".join(map("".join, world))

edit1:您可以像 TrebuchetMS 那样进行列表理解,但它实际上构建了一个列表,而在 python3 中,map 将创建一个迭代器,它不会在调用 "\n".map 之前不需要存储所有转换的行,而是动态计算转换行的列表,而不是将它们存储在列表中。

edit2:对于世界的部分渲染,只需在构建字符串之前使用列表的范围选择。例如,world[j1:j2] 仅包含从索引 j1(包括)到索引 j2(排除)的世界行。因此,如果您想要显示从 (i,j) 开始且尺寸为 (w,h) 的矩形,请执行:

displayedWorld = "\n".join(map(lambda row: "".join(row[i:i+w]), world[j:j+h]))

这是使用了一个新的习惯用法,lambda,它只是一个未命名的函数。 lambda lambda row: "".join(row) 等同于方法 "".join。因此 lambda row: "".join(row[i:i+w]) 仅合并行中从 ii+w 的案例。请注意,我们还只选择了世界上从 jj+h 的行。