PyGame:平移平铺地图会导致间隙 [英] PyGame: Panning tiled map causes gaps

查看:62
本文介绍了PyGame:平移平铺地图会导致间隙的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

I'm using PyGame 1.9.2 on Python 3.4.3 (Win8.1).

我的游戏窗口由一个使用 48x48px 瓷砖的平铺地图组成.游戏框架使用游戏框架类的以下方法根据玩家输入移动图块:

My game window consists of a tiled map using 48x48px tiles. The game's framework moves the tiles according to player input using the following method of the game's framwork class:

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] = 向下平移-左等).

While "self.panning_speed" is pretty self-explanatory, self.panning is a list containing two values for x and y panning (e.g. [0, 0] = no panning, [-1, 1] = panning down-left, etc.).

tile.x/tile.y 值然后被int'ed"以用作 rect 和 pos(后者用于 blitting)的 x/y 值.

The tile.x/tile.y values are then "int'ed" to be used as x-/y-values of the rect and the pos (the latter used for blitting).

我将完全相同的数量添加到每个瓷砖的 x/y 值,然后我在它们上使用int",据我所知,它总是将浮点数降到下一个较低的 int 值.所以从技术上看,每个瓦片的 x/y 值的相对变化与任何其他瓦片的 x/y 值完全相同.

I add the exact same amount to every single tile's x/y value, then I use "int" on them which, to my knowledge, always floors the float down to the next lower int. So technically seen the relative change to every single tile's x/y value is the exactly same as to any other tile's x/y value.

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

Yet: I still get gaps between rows or columns from time to time! Those gaps appear irregularly but are very visible and when you stop panning while a gap is visible that gap will stay until you pan again.

请参阅此图片以获取示例:示例请看这张图片(红色方块中的黑线是间隙;金色和粉色是瓷砖)

See this image for an example: See this image for an example (black line in the red square is the gap; gold and pink are the tiles)

我的代码中哪些地方会出现这些差距?

Where in my code can these gaps occur?

推荐答案

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

Here's a solution that should work better. Just add the velocity to the panning vector when the player is moving and never move the tiles. The panning is then added to the rect.topleft position of the tiles when they're blitted to get the correct position. You have to convert the panning to integers first (create another vector, called offset in the example) before you add it to the tile positions or you'll still get gaps.

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()

另一种选择是在程序启动时将图块 blit 到一个大的背景表面上.这样您就不会出现间隙,这也提高了性能.

Another alternative would be to blit the tiles onto a big background surface at program start. Then you won't get gaps and that also improves the performance.

这篇关于PyGame:平移平铺地图会导致间隙的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆