使用NumPy提高PyGame中更新函数的性能

2024-09-27 00:15:11 发布

您现在位置:Python中文网/ 问答频道 /正文

现在,pygame正在做很多很多计算来呈现我当前的项目。 我被告知NumPy可以帮助“解决”我的项目瓶颈。 关于如何实现它,我有一些想法,但我想知道你们是否对如何使用NumPy改进此更新功能的性能有任何想法/建议,那就太好了:)

功能说明: 当对象(即球)围绕hitGrid移动时,它通过其位置跟踪对象所在的位置,并将hitGrid中该位置的值减去1

我的代码:

# Variables
WIDTH, HEIGHT, MARGIN = 10, 10, 1
GRIDX, GRIDY = 100, 40
def update(self, boundrect, hitGrid, hitList):
    self.pos += self.vel
    self.rect.center = self.pos
    
    if self.rect.left <= boundrect.left or self.rect.right >= boundrect.right:
        self.vel.x *= -1                            
    if self.rect.top <= boundrect.top or self.rect.bottom >= boundrect.bottom:
        self.vel.y *= -1     

    # align rect to grid
    gridpos = round(self.rect.x / (WIDTH+MARGIN)), round(self.rect.y / (HEIGHT+MARGIN))
    self.rect.topleft = gridpos[0] * (WIDTH+MARGIN), gridpos[1] * (HEIGHT+MARGIN)

    # increment touched filed
    global max_hit
    max_hit = 100
    
    #numpy used here
    oldHitList = hitList[:]
    hitList.clear()
    for c in range(self.gridsize[0]):
        for r in range(self.gridsize[1]):
            p = gridpos[1] + r, gridpos[0] + c
            if p in oldHitList:
                hitList.append(p)
            elif self.grid[r][c] == 1:
                if p[0] < len(hitGrid) and p[1] < len(hitGrid[p[0]]):
                    hitList.append(p)
                    if p not in oldHitList:
                        hitGrid[p[0]][p[1]] -= 1
                        max_hit = min(max_hit, hitGrid[p[0]][p[1]])
# object used by gridObject
ballGrid = [[1]]

# How gridObject is initialized in main()
def main():
...
    sprite_group = pygame.sprite.Group()
    ball = GridObject((screen.get_width()//2, screen.get_height()//2), ballGrid, sprite_group)
    hitGrid = [[100 for i in range(GRIDX)] for j in range(GRIDY)]
    hitList = []
...
...
...
        # How the update fuction is used
        bounding_box = pygame.Rect(0,0,(GRIDX * (WIDTH + MARGIN) + MARGIN), (GRIDY * (HEIGHT + MARGIN)))
        sprite_group.update(bounding_box, hitGrid, hitList)

我的想法:

# in update
def update(self, boundrect, hitGrid, hitList):
...
   oldHitList = hitList[:]
   # How do you clear a np.array like you would a list?
   hitList.clear() # hitList = np.empty((GRIDX, GRIDY))?
   for c in range(self.gridsize[0]):
       for r in range(self.gridsize[1]):
           p = gridpos[1] + r, gridpos[0] + c
           if p in oldHitList:
               hitList.append(p) # hitList = np.append(hitList, p)
           elif self.grid[r][c] == 1:
               if p[0] < len(hitGrid) and p[1] < len(hitGrid[p[0]]):
                   hitList.append(p) # hitList = np.append(hitList, p)
                   if p not in oldHitList:
                       hitGrid[p[0]][p[1]] -= 1
                       max_hit = min(max_hit, hitGrid[p[0]][p[1]])
...
# in main
hitGrid = np.full((GRIDX, GRIDY), max_hit)
hitList = np.empty((GRIDX, GRIDY))

Tags: inmarginrectselfforifmaxhit

热门问题