Pygame 2d瓷砖滚动边缘不会加载

时间:2016-04-25 01:23:39

标签: python pygame 2d tile

我试图在pygame中制作一个有点像口袋妖怪的游戏。由于我不知道如何解决,我已经真的陷入了一个问题。

当我移动角色时,我会滚动地图,以便玩家保持居中。我创造了一个"动画"通过一次偏移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()

1 个答案:

答案 0 :(得分:2)

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

enter image description here

外边框是精灵屏幕,内边框是显示器。 你总是在屏幕的四周都有一个精灵。现在,如果您计算屏幕任何一侧的像素移动,您可以轻松跟踪何时需要绘制下一行或一列精灵,而不是它们总是在画面关闭。如果我的像素移动是-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

代码很容易理解,因为我已经对它们进行了评论。希望这会有所帮助。