【问题标题】:Pygame 2d tile scrolling edges don't loadPygame 2d瓷砖滚动边缘不加载
【发布时间】:2016-04-25 01:23:39
【问题描述】:

我正在尝试在 pygame 中制作一个 2d 游戏,有点像口袋妖怪。我现在真的陷入了一个我不知道如何解决的问题。

当我移动我的角色时,我会滚动地图以使玩家保持居中。我通过一次将距离偏移 2 个像素而不是移动整个图块大小来创建“动画”,因此我得到了平滑的移动。我遇到的问题是,当我移动时,屏幕不会在我移动的边缘加载新的瓷砖,所以边缘最终会变成一个空白区域,直到我完成完整的动画。我将链接我的代码,希望有人可以帮助我:)

TILESIZE = 32
MAP_WIDTH = 25
MAP_HEIGHT = 25

class Player(pygame.sprite.Sprite):
    def __init__(self, color, width, height):
        # Call the parent class (Sprite) constructor
        super().__init__()
        self.name = "Player"
        self.width = width
        self.height = height
        self.image = pygame.Surface([width, height])
        self.image.fill(color)
        self.rect = self.image.get_rect()
        self.rect.x = int(TILESIZE * (MAP_WIDTH / 2)) - TILESIZE / 2
        self.rect.y = int(TILESIZE * (MAP_HEIGHT / 2)) - TILESIZE / 2

class World:
    def __init__(self):
        self.shiftX = 0
        self.shiftY = 0
        self.tile_map = [ [DIRT for w in range(MAP_WIDTH)] for h in range(MAP_HEIGHT)]
        for row in range(MAP_HEIGHT):
            for column in range(MAP_WIDTH):
                try:
                    if real_map[row + self.shiftY][column + self.shiftX] == 0:
                        tile = DIRT
                    elif real_map[row + self.shiftY][column + self.shiftX] == 1:
                        tile = GRASS
                    elif real_map[row + self.shiftY][column + self.shiftX] == 2:
                        tile = WATER
                    else:
                        tile = DIRT
                    self.tile_map[row][column] = tile
                except:
                    self.tile_map[row][column] = WATER

    def shiftWorld(self):

        for row in range(MAP_HEIGHT):
            for column in range(MAP_WIDTH):
                try:
                    if real_map[row + self.shiftY][column + self.shiftX] == 0:
                        tile = DIRT
                    elif real_map[row + self.shiftY][column + self.shiftX] == 1:
                        tile = GRASS
                    elif real_map[row + self.shiftY][column + self.shiftX] == 2:
                        tile = WATER
                    else:
                        tile = DIRT
                    self.tile_map[row][column] = tile
                except:
                    self.tile_map[row][column] = WATER

    def okToMove(self, key):
        if key[K_w]:
            if self.tile_map[int(MAP_WIDTH/2 - 1)][int(MAP_HEIGHT/2)] != 2:
                return True
        elif key[K_s]:
            if self.tile_map[int(MAP_WIDTH/2 + 1)][int(MAP_HEIGHT/2)] != 2:
                return True
        elif key[K_a]:
            if self.tile_map[int(MAP_WIDTH/2)][int(MAP_HEIGHT/2) - 1] != 2:
                return True
        elif key[K_d]:
            if self.tile_map[int(MAP_WIDTH/2)][int(MAP_HEIGHT/2) + 1] != 2:
                return True

def start_game():
    pygame.init()
    clock = pygame.time.Clock()
    #HÄR KAN VI MÅLA UPP MER
    #SCREEN = pygame.display.set_mode((MAP_WIDTH*TILESIZE, MAP_HEIGHT*TILESIZE))
    world = World()
    SCREEN = pygame.display.set_mode((TILESIZE * (MAP_WIDTH-2), TILESIZE * (MAP_HEIGHT-4)))
    running = True
    player = Player(BLACK, 32, 32)
    sprites = pygame.sprite.Group()
    sprites.add(player)
    movement = 0
    offsetY = 0
    offsetX = 0
    animation_north = False
    animation_south = False
    animation_west = False
    animation_east = False

    while running:
        for event in pygame.event.get():
            if event.type==QUIT:
                pygame.quit()
                sys.exit()
            elif event.type == pygame.KEYDOWN:
                #Get keyinput and do whatever needs to be done
                key = pygame.key.get_pressed()
                if key[K_ESCAPE]:
                    pygame.quit()
                    sys.exit()

                if animation_east or animation_north or animation_south or animation_west:
                    pass
                else:
                    if key[K_w]:
                        okToMove = world.okToMove(key)
                        if okToMove == True:
                            animation_north = True
                        else:
                            pass
                    elif key[K_a]:
                        okToMove = world.okToMove(key)
                        if okToMove == True:
                            animation_west = True

                    elif key[K_s]:
                        okToMove = world.okToMove(key)
                        if okToMove == True:
                            animation_south = True

                    elif key[K_d]:
                        okToMove = world.okToMove(key)
                        if okToMove == True:
                            animation_east = True




        if animation_north == True:
            if movement == 32:
                movement = 0
                world.shiftY -= 1
                world.shiftWorld()
                offsetY = 0
                animation_north = False

            else:
                offsetY += 4
                movement += 4

        if animation_south == True:
            if movement == 32:
                movement = 0
                world.shiftY += 1
                world.shiftWorld()
                offsetY = 0
                animation_south = False
                intY = 0
            else:
                offsetY -= 4
                movement += 4

        if animation_west == True:
            if movement == 32:
                movement = 0
                world.shiftX -= 1
                world.shiftWorld()
                offsetX = 0
                animation_west = False
            else:
                offsetX += 4
                movement += 4

        if animation_east == True:
            if movement == 32:
                world.shiftX += 1
                world.shiftWorld()
                movement = 0
                offsetX = 0
                animation_east = False
            else:
                offsetX -= 4
                movement += 4


        SCREEN.fill(WHITE)

        for row in range(MAP_HEIGHT):
            for column in range(MAP_WIDTH):
                SCREEN.blit(textures[world.tile_map[row][column]], (column*TILESIZE + offsetX, row*TILESIZE + offsetY))


        sprites.draw(SCREEN)
        pygame.display.update()
        pygame.display.flip()
        clock.tick(60)

start_game()

【问题讨论】:

    标签: python pygame 2d tile


    【解决方案1】:

    我正在写一个类似的游戏,我会和你分享我的逻辑。 我的块是 32x32,所以每个块是 32 像素。

    外边框是精灵屏幕,内框是显示器。 你总是在屏幕的每一侧都有一个额外的精灵。现在,如果您计算屏幕任何一侧的像素移动,您可以轻松跟踪何时需要绘制下一行或下一列精灵,但并不总是将它们从屏幕上绘制出来。如果我的像素移动为-8(向左移动),我会在屏幕边框的右侧绘制一列精灵,但在可见区域之外。另一边也一样。

    这是我程序中的一些代码。这是精灵添加代码。

        def add_sprites(self):
    
        """sprites are added to the group which appear on screen right. the column number is the value in ColDrawn. We selct columns from the list according to this value. Once the end of the column list is reached we start again from the first one. We cycle thru the list depending on the NumCycle[0] value."""
    
        if self.ColDrawn < self.Columns_in_Dungeon - 1:
            self.ColDrawn += 1
    
        else:  # all the columns drawn so increment the flag
            self.ColDrawn = 0
            self.NumCycle[1] += 1
    
        if self.NumCycle[1] >= self.NumCycle[0]:  # if the flag is equal to the number of cycles the screen is scrolled then set numcycle[2] to True
            self.NumCycle[2] = True
    
        else:  # screen can be scrolled
            spritecol = self.all_wall_sprite_columns_list[self.ColDrawn]
            self.wallspritegroup.add(spritecol)  # add column of sprites to the sprite group
        return
    

    这里是精灵移除代码。

        def remove_sprites(self):
    
        """sprites are removed from the group as they exit from screen left."""
    
        for sprt in self.wallspritegroup:  # remove_basic sprites that move_basic off screen on left
    
            if sprt.rect.x <= -48:
                sprt.rect.x = self.screenw # reset the x position and
                sprt.kill()
                #spritegrp.remove_basic(sprt)  # remove_basic the sprite from the sprite group
    
        return
    

    正如我评论过的那样,代码很容易理解。希望这会有所帮助。

    【讨论】:

    • 我通过改变: SCREEN = pygame.display.set_mode((TILESIZE * (MAP_WIDTH), TILESIZE * (MAP_HEIGHT))) 到: SCREEN = pygame.display.set_mode( (TILESIZE * (MAP_WIDTH-1), TILESIZE * (MAP_HEIGHT-1)))。非常感谢你的帮忙!我的问题是我如何绘制现在应该是负数的框架?屏幕上方的瓷砖和左边的瓷砖!感谢您到目前为止的帮助!
    • 如果您接受我的帮助,您可以将其标记为已接受。 :) 请详细说明问题。 “绘制应该为负的框架?屏幕上方的图块和左侧的图块!”是什么意思?为什么需要画这些?他们不是在可见的屏幕区域之外吗?
    • 好的,我会尽力的。屏幕上方和屏幕左侧的图块确实在可见区域之外。我的问题是,当我移动我的角色时,我绘制了一个偏移量: (columnTILESIZE + offsetX, rowTILESIZE + offsetY)) 所以它在偏移区域中显示的是白色: SCREEN.fill( WHITE)我在想,如果我可以在可见屏幕之外在每个方向上绘制 1 个图块,它绘制的偏移量就不会是白色,而是下一个图块!
    • 是的,您可以在屏幕区域外的各个方向上绘制一个额外的图块。这就是我在上图中向您展示的内容。您应该将地图绘制为文本文件并从中获取屏幕位置。这样你就可以创建一个例程来读取 txt 文件并将精灵绘制到屏幕上。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-11-19
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多