python - PyGame:平移平铺 map 会导致间隙

标签 python pygame tile

我在 Python 3.4.3 (Win8.1) 上使用 PyGame 1.9.2。

我的游戏窗口由一个使用 48x48 像素方 block 的方 block map 组成。游戏框架使用以下游戏框架类的方法根据玩家输入移动方 block :

def moveTiles(self):
    xmove = self.parent.dt * self.panning[0] * self.panning_speed
    ymove = self.parent.dt * self.panning[1] * self.panning_speed
    for tile in self.game_map:
        tile.x += xmove
        tile.y += ymove
        tile.rect.x = int(tile.x)
        tile.rect.y = int(tile.y)
        tile.pos = (tile.rect.x, tile.rect.y)

虽然“self.panning_speed”是不言自明的,但 self.panning 是一个列表,其中包含 x 和 y 平移的两个值(例如 [0, 0] = 无平移,[-1, 1] = 向下平移-左等)。

然后将 tile.x/tile.y 值“int'ed”用作 rect 和 pos 的 x/y 值(后者用于 blitting)。

我将完全相同的数量添加到每个图 block 的 x/y 值,然后我在它们上使用“int”,据我所知,它总是将 float 向下一个较低的 int。因此从技术上看,每个图 block 的 x/y 值的相对变化与任何其他图 block 的 x/y 值的相对变化完全相同。

然而:我仍然时不时地在行或列之间出现间隙!这些间隙不规则出现但非常明显,当您在间隙可见时停止平移时,间隙将一直存在,直到您再次平移。

请参阅此图片作为示例: See this image for an example (black line in the red square is the gap; gold and pink are the tiles)

这些差距会出现在我的代码中的什么地方?

最佳答案

这是一个应该能更好地工作的解决方案。只需在玩家移动时将 velocity 添加到 panning 向量中,不要移动方 block 。然后平移被添加到图 block 的 rect.topleft 位置,当它们被 block 化以获得正确的位置时。您必须先将平移转换为整数(创建另一个向量,在示例中称为 offset),然后再将其添加到平铺位置,否则您仍然会出现间隙。

import itertools
import pygame as pg
from pygame.math import Vector2


TILE_SIZE = 44
TILE_IMG1 = pg.Surface((TILE_SIZE, TILE_SIZE))
TILE_IMG1.fill(pg.Color('dodgerblue3'))
TILE_IMG2 = pg.Surface((TILE_SIZE, TILE_SIZE))
TILE_IMG2.fill(pg.Color('aquamarine3'))


class Tile(pg.sprite.Sprite):

    def __init__(self, pos, image):
        super().__init__()
        self.image = image
        self.rect = self.image.get_rect(topleft=pos)
        self.pos = Vector2(pos)


def main():
    screen = pg.display.set_mode((640, 480))
    clock = pg.time.Clock()
    dt = 0

    image_cycle = itertools.cycle((TILE_IMG1, TILE_IMG2))
    game_map = pg.sprite.Group()
    # Create tile instances and add them to the game map group.
    for y in range(16):
        for x in range(20):
            image = next(image_cycle)
            game_map.add(Tile((x*TILE_SIZE, y*TILE_SIZE), image))
        next(image_cycle)

    panning = Vector2(0, 0)
    velocity = Vector2(0, 0)

    done = False

    while not done:
        for event in pg.event.get():
            if event.type == pg.QUIT:
                done = True
            elif event.type == pg.KEYDOWN:
                if event.key == pg.K_a:
                    velocity.x = 100
                elif event.key == pg.K_d:
                    velocity.x = -100
            elif event.type == pg.KEYUP:
                if event.key == pg.K_d and velocity.x < 0:
                    velocity.x = 0
                elif event.key == pg.K_a and velocity.x > 0:
                    velocity.x = 0

        # Add the velocity to the panning when we're moving.
        if velocity.x != 0 or velocity.y != 0:
            panning += velocity * dt

        game_map.update()

        screen.fill((30, 30, 30))
        # Assigning screen.blit to a local variable improves the performance.
        screen_blit = screen.blit
        # Convert the panning to ints.
        offset = Vector2([int(i) for i in panning])
        # Blit the tiles.
        for tile in game_map:
            # Add the offset to the tile's rect.topleft coordinates.
            screen_blit(tile.image, tile.rect.topleft+offset)

        pg.display.flip()
        dt = clock.tick(30) / 1000


if __name__ == '__main__':
    pg.init()
    main()
    pg.quit()

另一种替代方法是在程序启动时将图 block block block 化到大背景表面上。这样就不会出现间隙,这也会提高性能。

关于python - PyGame:平移平铺 map 会导致间隙,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48034044/

相关文章:

python - 应如何创建 StackDriver 条目?

python - Elasticsearch计算后将两个字段回填到一个新字段中

python,pyserial读取回复数据

python - 碰撞不断真实吗?

java - 如何存储巨大的瓦片 map ?

c# - XNA 使用 2D 相机查找鼠标位置

python - 如何使用 AES-256-CCM 在 php 中通过 python 解密加密文本

Python Pygame 使用共享调用时传递参数

CSS:给一个div一个高度是一个数字的倍数?

python - 如何在 pygame 中添加一条线作为 Sprite ?