使用python和pytmx渲染和刷新tmx文件映射

问题描述

我使用pytmx用pygame加载我的地​​图,但有些项目需要设置为精灵并显示在表面上方,所以分层不会停留,我将向您展示2个示例,一个是播放器显示在装饰的顶部(装饰下方的点层)另一个显示在墙壁上方的门。

我尝试通过从 Renderer 重写 make_map() 和 render(surface) 函数来使用我的玩家和门对象刷新我的地图,但是我迭代的不是传递对象而是将它们扔到原来的 blit 对象上,它有显示,但是还是没有分层,帧数也下降了一半。

Si 如果有人知道如何在播放器和其他用于渲染动画精灵的对象中保持分层,我很乐意得到您的帮助。

Player on top of the decorations

Layering in my map editor

Door in my game

Door in the map editor

这是我每次尝试使用分层刷新地图的代码(它正在显示,但它的结果与我只绘制表面然后在上面绘制精灵完全相同):


    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))
            
        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 精灵组 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))

        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,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,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,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,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,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()

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...