使用 python 和 pytmx 渲染和刷新 tmx 文件映射
Rendering and refreshing tmx file map with python and pytmx
我正在使用 pytmx 通过 pygame 加载我的地图,但有些项目需要设置为 sprite 并显示在表面上方,因此分层不会保留,我将向您展示 2 个示例,一种是玩家显示在装饰物之上(点层在装饰物下方)另一种是门显示在墙上方。
我试图通过重写渲染器中的 make_map() 和渲染(表面)函数来用我的播放器和门对象刷新我的地图,但我没有传递对象,而是将它们迭代扔给了原来的对象, 有显示, 但还是不分层, 还掉了一半FPS.
如果有人知道如何在播放器和其他用于渲染动画精灵的对象中保持分层,我很乐意得到你的帮助。
这是我每次尝试使用分层刷新地图的代码(它正在显示,但它的结果与我只绘制表面然后在上面绘制精灵的结果完全相同):
def draw(self, display, camera = None):
self.surface = self.make_map()
self.rect = self.surface.get_rect()
if not camera:
display.blit(self.surface, self.rect)
else:
display.blit(self.surface, (self.rect.x - camera.offset.x, self.rect.y - camera.offset.y))
def render(self, surface):
tw = self.tmx_data.tilewidth
th = self.tmx_data.tileheight
if self.tmx_data.background_color:
surface.fill(self.tmx_data.background_color)
else:
surface.fill((0, 0, 0))
for layer in self.tmx_data.layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x, y, image in layer.tiles():
if image:
surface.blit(image.convert_alpha() , (x * tw, y * th))
elif isinstance(layer, pytmx.TiledObjectGroup):
for tile_object in layer:
if tile_object.name == 'player':
surface.blit(self.level.game.player.image.convert_alpha(), (self.level.game.player.rect.x, self.level.game.player.rect.y))
if tile_object.name == 'door':
for door in self.level.game.doors:
if door.type == tile_object.type:
surface.blit(door.image.convert_alpha(), (door.rect.x, door.rect.y))
elif isinstance(layer, pytmx.TiledImageLayer):
if image:
surface.blit(image , (0, 0))
def make_map(self):
temp_surface = pygame.Surface(self.renderer.size)
self.render(temp_surface)
return temp_surface
所以我找到了一种方法来获得我想要的东西,我使用了 pyagme sprites groups layeredUpdates,我添加到我的原始地图只有地板,我用我的其他层(墙壁,装饰)创建了分层精灵然后显示与图层
地图渲染
def render(self, surface):
tw = self.tmx_data.tilewidth
th = self.tmx_data.tileheight
if self.tmx_data.background_color:
surface.fill(self.tmx_data.background_color)
else:
surface.fill((0, 0, 0))
for layer in self.tmx_data.layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x, y, image in layer.tiles():
if image:
if layer.name == 'walls' or 'wall' in layer.name:
Wall(self.game, x * tw, y * th, image.convert_alpha())
elif 'decoration' in layer.name:
Decoration(self.game, x * tw, y * th, image.convert_alpha())
else:
surface.blit(image.convert_alpha() , (x * tw, y * th))
elif isinstance(layer, pytmx.TiledObjectGroup):
pass
elif isinstance(layer, pytmx.TiledImageLayer):
if image:
surface.blit(image , (0, 0))
def make_map(self):
temp_surface = pygame.Surface(self.size)
self.render(temp_surface)
return temp_surface
对象:
class Decoration(pygame.sprite.Sprite):
def __init__(self, game, x, y, image, layer = DECORATION_TOP_LAYER):
self.groups = game.all_sprites, game.decorations
self._layer = layer
pygame.sprite.Sprite.__init__(self, self.groups)
class Wall(pygame.sprite.Sprite):
def __init__(self, game, x, y, image):
self.groups = game.all_sprites, game.walls
self._layer = WALL_LAYER
pygame.sprite.Sprite.__init__(self, self.groups)
class Door(pygame.sprite.Sprite):
def __init__(self, game, x, y, w, h, open_actions, animated_image, type):
self._layer = DOOR_LAYER
self.groups = game.all_sprites, game.doors
pygame.sprite.Sprite.__init__(self, self.groups)
class NPC(pygame.sprite.Sprite):
def __init__(self, game, x, y, w, h, animated_image):
self.groups = game.all_sprites, game.NPCs
self._layer = NPC_LAYER
pygame.sprite.Sprite.__init__(self, self.groups)
让所有东西一起工作的原因很简单:
self.all_sprites = pygame.sprite.LayeredUpdates()
我正在使用 pytmx 通过 pygame 加载我的地图,但有些项目需要设置为 sprite 并显示在表面上方,因此分层不会保留,我将向您展示 2 个示例,一种是玩家显示在装饰物之上(点层在装饰物下方)另一种是门显示在墙上方。
我试图通过重写渲染器中的 make_map() 和渲染(表面)函数来用我的播放器和门对象刷新我的地图,但我没有传递对象,而是将它们迭代扔给了原来的对象, 有显示, 但还是不分层, 还掉了一半FPS.
如果有人知道如何在播放器和其他用于渲染动画精灵的对象中保持分层,我很乐意得到你的帮助。
这是我每次尝试使用分层刷新地图的代码(它正在显示,但它的结果与我只绘制表面然后在上面绘制精灵的结果完全相同):
def draw(self, display, camera = None):
self.surface = self.make_map()
self.rect = self.surface.get_rect()
if not camera:
display.blit(self.surface, self.rect)
else:
display.blit(self.surface, (self.rect.x - camera.offset.x, self.rect.y - camera.offset.y))
def render(self, surface):
tw = self.tmx_data.tilewidth
th = self.tmx_data.tileheight
if self.tmx_data.background_color:
surface.fill(self.tmx_data.background_color)
else:
surface.fill((0, 0, 0))
for layer in self.tmx_data.layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x, y, image in layer.tiles():
if image:
surface.blit(image.convert_alpha() , (x * tw, y * th))
elif isinstance(layer, pytmx.TiledObjectGroup):
for tile_object in layer:
if tile_object.name == 'player':
surface.blit(self.level.game.player.image.convert_alpha(), (self.level.game.player.rect.x, self.level.game.player.rect.y))
if tile_object.name == 'door':
for door in self.level.game.doors:
if door.type == tile_object.type:
surface.blit(door.image.convert_alpha(), (door.rect.x, door.rect.y))
elif isinstance(layer, pytmx.TiledImageLayer):
if image:
surface.blit(image , (0, 0))
def make_map(self):
temp_surface = pygame.Surface(self.renderer.size)
self.render(temp_surface)
return temp_surface
所以我找到了一种方法来获得我想要的东西,我使用了 pyagme sprites groups layeredUpdates,我添加到我的原始地图只有地板,我用我的其他层(墙壁,装饰)创建了分层精灵然后显示与图层
地图渲染
def render(self, surface):
tw = self.tmx_data.tilewidth
th = self.tmx_data.tileheight
if self.tmx_data.background_color:
surface.fill(self.tmx_data.background_color)
else:
surface.fill((0, 0, 0))
for layer in self.tmx_data.layers:
if isinstance(layer, pytmx.TiledTileLayer):
for x, y, image in layer.tiles():
if image:
if layer.name == 'walls' or 'wall' in layer.name:
Wall(self.game, x * tw, y * th, image.convert_alpha())
elif 'decoration' in layer.name:
Decoration(self.game, x * tw, y * th, image.convert_alpha())
else:
surface.blit(image.convert_alpha() , (x * tw, y * th))
elif isinstance(layer, pytmx.TiledObjectGroup):
pass
elif isinstance(layer, pytmx.TiledImageLayer):
if image:
surface.blit(image , (0, 0))
def make_map(self):
temp_surface = pygame.Surface(self.size)
self.render(temp_surface)
return temp_surface
对象:
class Decoration(pygame.sprite.Sprite):
def __init__(self, game, x, y, image, layer = DECORATION_TOP_LAYER):
self.groups = game.all_sprites, game.decorations
self._layer = layer
pygame.sprite.Sprite.__init__(self, self.groups)
class Wall(pygame.sprite.Sprite):
def __init__(self, game, x, y, image):
self.groups = game.all_sprites, game.walls
self._layer = WALL_LAYER
pygame.sprite.Sprite.__init__(self, self.groups)
class Door(pygame.sprite.Sprite):
def __init__(self, game, x, y, w, h, open_actions, animated_image, type):
self._layer = DOOR_LAYER
self.groups = game.all_sprites, game.doors
pygame.sprite.Sprite.__init__(self, self.groups)
class NPC(pygame.sprite.Sprite):
def __init__(self, game, x, y, w, h, animated_image):
self.groups = game.all_sprites, game.NPCs
self._layer = NPC_LAYER
pygame.sprite.Sprite.__init__(self, self.groups)
让所有东西一起工作的原因很简单:
self.all_sprites = pygame.sprite.LayeredUpdates()