Python、Pygame和碰撞检测效率

Python、Pygame和碰撞检测效率,python,vector,pygame,Python,Vector,Pygame,我正在制作一个自上而下的侧面滚动游戏,带有一个自定义的精灵类(不是pygame.sprite) sprite collide()函数导致帧速率下降(我使用了cProfile) 请帮我找出问题所在 该功能以以下一般方式运行: def collide(self): for tile in tiles: if tile.type == 'wall': if self.getDist(tile.rect.center) < 2

我正在制作一个自上而下的侧面滚动游戏,带有一个自定义的精灵类(不是pygame.sprite

sprite collide()函数导致帧速率下降(我使用了
cProfile

请帮我找出问题所在

该功能以以下一般方式运行:

def collide(self):
        for tile in tiles:
            if tile.type == 'wall':
                if self.getDist(tile.rect.center) < 250:
                    if self.rect.colliderect(tile.rect):
                        return True
def碰撞(自):
对于瓷砖中的瓷砖:
如果tile.type==“墙”:
如果self.getDist(tile.rect.center)<250:
如果self.rect.collide rect(tile.rect):
返回真值
  • 查找精灵和所有墙砖之间的距离向量非常耗时
  • 我认为运行
    rect.colliderect()
    仅对250像素内的分幅运行会更快;但显然不是
  • 我没有包括源代码,因为我正在寻找更多的概念性答案来解决冲突检测效率低下的问题
  • 一个可能的解决方案是为不同的瓷砖组(即墙列表、地列表)创建单独的列表,但是,我真的认为如何搜索瓷砖对象列表存在一个基本问题


    我是StackOverflow新手,因此,如果我的问题结构/缺少源代码冒犯了您,请原谅。

    我没有检查地图中的每个磁贴以进行碰撞检测,而是创建了一个函数来标识精灵的当前磁贴,然后返回其八个相邻磁贴磁贴扫描方法:

    def scanTiles(self):
        m = curMap.map # this is a 2d matrix filled with tile-objects 
        x = int(self.trueX) # trueX & trueY allow me to implement
        y = int(self.trueY) # a 'camera system'
        curTile = m[y // T_SIZE[1]][x // T_SIZE[0]] 
        i = curTile.index # (x, y) coordinate of tile on map
    
        nw = None # northwest
        n = None # north
        ne = None # northeast
        e = None # east
        se = None # southeast
        s = None # south
        sw = None # southwest
        w = None # west
    
        # Each if-statement uses map indices
        # to identify adjacent tiles. Ex:
        # NW  N  NE
        # W  CUR  E
        # SW  S  SE
    
        if i[0] > 0 and i[1] > 0:
            nw = m[i[1]-1][i[0]-1]
        if i[1] > 0:
            n = m[i[1]-1][i[0]]
        if i[0] < len(m[0])-1 and i[1] > 0:
            ne = m[i[1]-1][i[0]+1]
        if i[0] < len(m[0])-1:
            e = m[i[1]][i[0]+1]
        if i[0] < len(m[0])-1 and i[1] < len(m)-1:
            se = m[i[1]+1][i[0]+1]
        if i[1] < len(m)-1:
            s = m[i[1]+1][i[0]]
        if i[1] < len(m)-1 and i[0] > 0:
            sw = m[i[1]+1][i[0]-1]
        if i[0] > 0:
            w = m[i[1]][i[0]-1]
        return [nw, n, ne, e, se, s, sw, w]
    
    def collide(self, adjTiles): # adjTiles was returned from scanTiles()
        for tile in adjTiles:
            if tile:             # if a tile actually exists, it continues
                if tile.type == 'wall': # tile type can either be 'ground' or 'wall'
                    if self.rect.colliderect(tile.rect1):
                        return True # if there is a collision, it returns 'True'
    

    这种新方法被证明更有效,现在已经解决了我的问题。

    Wow。代码格式真的发生了最坏的变化。很抱歉在要格式化的代码之前添加4个空格correctly@user3155622我编辑了它,您可以通过单击
    edit
    查看源代码,以查看如何正确格式化。@Nabla我签出了它。这很有帮助,谢谢。我不会将此作为一个答案发布,因为我对游戏开发一无所知,但是平铺地图的概念是不是,整个地图被划分为具有固定坐标的平铺,所以你只需要检查目标平铺(及其邻居)是否可访问,消除所有循环?