【问题标题】:How to render an isometric tile-based world in Python?如何在 Python 中渲染基于等距平铺的世界?
【发布时间】:2013-12-17 09:03:56
【问题描述】:

我在使用以下代码使用 Python 和 Pygame 渲染基于等距 2D 瓦片的世界时遇到了一些问题:

'''
Map Rendering Demo
rendermap.py
By James Walker (trading as Ilmiont Software).
Copyright (C)Ilmiont Software 2013. All rights reserved.

This is a simple program demonstrating rendering a 2D map in Python with Pygame from a list of map data.
Support for isometric or flat view is included.
'''

import pygame
from pygame.locals import *

pygame.init()

DISPLAYSURF = pygame.display.set_mode((640, 480), DOUBLEBUF)    #set the display mode, window title and FPS clock
pygame.display.set_caption('Map Rendering Demo')
FPSCLOCK = pygame.time.Clock()

map_data = [
[1, 1, 1, 1, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 0, 0, 0, 1],
[1, 1, 1, 1, 1]
]               #the data for the map expressed as [row[tile]].

wall = pygame.image.load('wall.png').convert()  #load images
grass = pygame.image.load('grass.png').convert()

tileWidth = 64  #holds the tile width and height
tileHeight = 64

currentRow = 0  #holds the current map row we are working on (y)
currentTile = 0 #holds the current tile we are working on (x)

for row in map_data:    #for every row of the map...
    for tile in row:
        tileImage = wall

        cartx = currentTile * 64    #x is the index of the currentTile * the tile width
        print(cartx)
        carty = currentRow * 64     #y is the index of the currentRow * the tile height
        print(carty)
        x = cartx - carty
        print(x)
        y = (cartx + carty) / 2
        print(y)
        print('\n\n')
        currentTile += 1    #increase the currentTile holder so we know that we are starting rendering a new tile in a moment

        DISPLAYSURF.blit(tileImage, (x, y)) #display the actual tile
    currentTile = 0 #reset the current working tile to 0 (we're starting a new row remember so we need to render the first tile of that row at index 0)
    currentRow += 1 #increment the current working row so we know we're starting a new row (used for calculating the y coord for the tile)

while True:
    for event in pygame.event.get():
        if event.type == QUIT:
            pygame.quit()
            sys.exit()
        if event.type == KEYUP:
            if event.key == K_ESCAPE:
                pygame.quit()
                sys.exit()

    pygame.display.flip()
    FPSCLOCK.tick(30)

使用的图块大小为 64x64;上面的代码在运行时会生成以下输出: 瓷砖都有透明的边缘,本例中只有“墙”瓷砖,但显然有问题,因为瓷砖相距太远。

我尝试在线阅读一些教程,但似乎找不到真正用 Python 编写的教程,因此请告知我哪里出错了。

提前致谢, 伊尔蒙

【问题讨论】:

    标签: python pygame render tile isometric


    【解决方案1】:

    试试这个:

      print(carty)
      x = (cartx - carty) / 2
      print(x)
      y = (cartx + carty)/4*3
    

    并且,经过测试,将 convert() 修改为 convert_alpha(),因为优化会在 convert() 上杀死 alpha

    我还修改了 y ( /4*3 ),以考虑您的形象。这对我有用。

    【讨论】:

    • 效果更好,但我现在得到了这个结果:i.stack.imgur.com/XJgBC.png 所以黑色三角形(部分)仍然存在。
    • 你确定那些黑色的部分是透明的吗?
    • 你能把你的map.png贴在附件里吗?你也可以试试:wall = pygame.image.load('wall.png').convert_alpha()
    • 这里是我展示的“wall.png”图块:i.stack.imgur.com/oBrF0.png
    • 哎呀,对不起... A.H 是对的;我还没有转换为 alpha。所以现在地图可以正确渲染,但它仍然不是正确的形状......我如何在屏幕中心渲染它???
    【解决方案2】:

    您可以通过将颜色键设置为黑色来消除黑色三角形,我复制了您的示例并能够通过更改来修复它:

    for row in map_data:    #for every row of the map...
    for tile in row:
        tileImage = wall
    

    for row in map:
      for tile in row:
        tileImage = wall
        tileImage.set_colorkey((0,0,0))
    

    发现于: https://www.pygame.org/docs/ref/surface.html#pygame.Surface.set_colorkey

    可能有更好的方法来为所有人设置颜色键,但我试过了,它似乎有效。我看到关于 alpha 的评论,我相信它也会更好。

    关于定位,您只需要从屏幕中间开始渲染。通过简单的更改,我可以用你的代码做到这一点:

    x = cartx - carty
    print(x)
    y = (cartx + carty) / 2
    

    x = 320 + ((cartx - carty) / 2)
    y = ((cartx+carty) / 4 * 3)
    

    我希望这可以帮助到这个帖子的任何新人!

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2013-04-06
      相关资源
      最近更新 更多