【发布时间】: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 值,以便在每次加载新地图时将它们加载到正确的坐标中(并且因为地图在我的游戏和原版塞尔达一样,新地图加载非常频繁。)
【问题讨论】: