如何解决独立于瓷砖地图加载播放器
所以我正在 PyGame 中开发一个自上而下的游戏,我刚刚实现了加载不同的地图。唯一的问题是,玩家是在地图中加载的,所以如果玩家在地图左侧加载,则前往地图右侧的出口,将他们带到第二张地图,他们将再次在左侧渲染的地图。但是当玩家回到原始地图时,它们仍然会加载到地图的左侧,而不是它们来自的地图右侧。
瓷砖贴图的存储方式如下:
class tilemap01():
def __init__(self):
self.mapdata = [
'1111111111111111111111111111111111111111','1111111111111111111111111111111111111111','1000000000000000000000000000000000000001','1000000000000000000000000000000R00000001','10P0000000000000000000000000000000000001','100000000000000000000000000000000000000T','100000000000000000R000000H0000000000000T',]
self.links = {
(39,11): 'tilemap02',(39,12): 'tilemap02',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,i)
if column == 'P':
self.player = Player(self,i)
if column == 'R':
rover(self,i)
if column == 'T':
map_change_trigger(self,i)
if column == 'H':
house(self,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,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 值以在每次加载新地图时将它们加载到正确的坐标中(并且因为地图在我的游戏就像在原始塞尔达一样,新地图加载非常频繁。)
解决方法
玩家(和任何其他动态对象)不是地图的一部分。玩家在地图上。玩家下方是草(或类似的东西)。玩家只有一个位置(坐标)来定义他在地图上的位置。
从地图中移除玩家,但添加一个存储玩家起始位置的属性。绘制场景时,先绘制地图,然后在地图上绘制玩家。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。