独立于tilemap加载播放器



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

以下是瓷砖贴图的存储方式:

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是存储我导入的所有tilemap的文件名。

这是玩家类初始化函数:

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中字典的一个键关闭时通知我,并在发生这种情况时阻止游戏崩溃。

这就是所有相关的代码。我在这里要做的是独立于tilemap加载玩家,这样它就不会被静态加载,并存储玩家的x和y值,以便在每次加载新地图时将其加载到正确的坐标中(由于我的游戏中的地图与原始塞尔达中的地图类似,所以新地图会非常频繁地加载到中。(

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

最新更新