【问题标题】:Loading the player independently from the tilemap独立于瓷砖地图加载播放器
【发布时间】:2021-07-03 18:03:05
【问题描述】:

所以我正在 PyGame 中开发一个自上而下的游戏,我刚刚实现了加载不同的地图。唯一的问题是,播放器是在瓦片地图中加载的,所以如果一个播放器加载在地图的左侧,然后到地图右侧的出口将他们带到第二张地图,他们将再次在左侧渲染的地图。但是当玩家回到原来的地图时,他们仍然会被加载到地图的左侧,而不是他们来自的地图的右侧。

瓦片地图的存储方式如下:

class tilemap01():

def __init__(self):
    
    self.mapdata = [
        '1111111111111111111111111111111111111111', 
        '1111111111111111111111111111111111111111',
        '1111111111111111111111111111111111111111', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000R00000001', 
        '10P0000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '100000000000000000000000000000000000000T',
        '100000000000000000R000000H0000000000000T', 
        '100000000000000000000000000000000000000T', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000R00000001', 
        '1000000000000000000000000000000000000001',
        '1000000000000000000000000000000000000001', 
        '1000000000000000000000000000000000000001', 
        '1111111111111111111111111111111111111111', 
        ]

    self.links = {
    (39, 11): 'tilemap02',
    (39, 12): 'tilemap02',
    (39, 13): 'tilemap02'
    }

self.links 确定当前地图中的哪些图块通向其他类似存储的地图。

下面是瓦片地图的实际加载方式:

def setTilemap(self, tilemap):
    tilemap = getattr(leveldata, tilemap)
    self.tilemap = tilemap()
    self.new()

def TileCreate(self):

    for i, row in enumerate(self.tilemap.mapdata):
        for j, column in enumerate(row):
            grass(self, j, i)
            if column == '1':
                block(self, j, i)
            if column == 'P':
                self.player = Player(self, j, i)
            if column == 'R':
                rover(self, j, i)
            if column == 'T':
                map_change_trigger(self, j, i)
            if column == 'H':
                house(self, j, i)

self.tilemap 在 Game 类的初始化中定义。 leveldata 是存储我导入的所有瓦片地图的文件的名称。

播放器类初始化函数如下:

class Player(pygame.sprite.Sprite):
def __init__(self, game, x, y):

    self.game = game
    self._layer = p_layer
    self.groups = self.game.all_sprites
    pygame.sprite.Sprite.__init__(self, self.groups)
    pygame.mixer.pre_init(44100, 16, 2, 32) #frequency, size, channels, buffersize

    self.x = x * TileSize
    self.y = y * TileSize
    self.x_change = 0
    self.y_change = 0

    self.facing = 'down'
    self.an_loop = 0
    self.footstep_timer = 0

    self.width = TileSize
    self.height = TileSize

    self.image = self.game.playerspritesheet.get_sprite(0, 0, 32, 32)

    self.rect = self.image.get_rect()
    self.rect.x = self.x
    self.rect.y = self.y

不确定这是否相关,但这里是玩家移动:

    def movement(self):
    keys = pygame.key.get_pressed()

    if self.footstep_timer > 0:
        self.footstep_timer -= 1

    if self.footstep_timer == 0:
        self.footstep_timer = 20

    if keys[pygame.K_w]:

        self.y_change -= PlayerVel
        self.facing = 'up'

        if self.footstep_timer == 20:
            random.choice(self.footsteps).play()

    if keys[pygame.K_a]:

        self.x_change -= PlayerVel
        self.facing = 'left'

        if self.footstep_timer == 20:
            random.choice(self.footsteps).play()

    if keys[pygame.K_s]:

        self.y_change += PlayerVel
        self.facing = 'down'

        if self.footstep_timer == 20:
            random.choice(self.footsteps).play()

    if keys[pygame.K_d]:

        self.x_change += PlayerVel
        self.facing = 'right'

        if self.footstep_timer == 20:
            random.choice(self.footsteps).play()

这可能是一个非常重要的部分:一个确定玩家与地图更改触发器发生碰撞的函数,当发生碰撞时会加载新地图:

def mct_collision(self):
    hits = pygame.sprite.spritecollide(self, self.game.triggers, False)
    if hits:
        key = (int(hits[0].rect.left/TileSize), int(hits[0].rect.top/TileSize))
        if key in self.game.tilemap.links:
            self.game.setTilemap(self.game.tilemap.links[key])
        else:
            print('bad collision')

打印是在 leveldata 中的字典键之一关闭时通知我,并在发生这种情况时阻止游戏崩溃。

这就是所有相关代码。我在这里尝试做的是独立于瓷砖地图加载播放器,以便它不会静态加载并存储播放器的 x 和 y 值,以便在每次加载新地图时将它们加载到正确的坐标中(并且因为地图在我的游戏和原版塞尔达一样,新地图加载非常频繁。)

【问题讨论】:

    标签: python pygame


    【解决方案1】:

    玩家(和任何其他动态对象)不是地图的一部分。玩家在地图上。玩家下方是草(或类似的东西)。玩家只有一个位置(坐标)来定义他在地图上的位置。
    从地图中移除玩家,但添加一个存储玩家起始位置的属性。绘制场景时,先绘制地图,再在地图上绘制玩家。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-12-14
      • 2016-10-11
      • 1970-01-01
      • 2019-05-10
      • 1970-01-01
      • 2013-02-11
      • 1970-01-01
      相关资源
      最近更新 更多