如何在Pygame中检测Sprite和Rect之间的冲突

时间:2019-07-06 01:27:42

标签: python pygame

我一直在玩GitHub Noops Challenges(https://noopschallenge.com/challenges) 迷上了迷宫机器人的挑战,我用python和PyGame模块创建了一个小游戏,在其中我根据请求(https://api.noopschallenge.com/mazebot/random?minSize=10&maxSize=10)提供的JSON字符串生成网格。


while(True):
        if(x_pos == 400):
            x_pos = 0
            y_pos += hight
            c += 1
            r = 0
        if(y_pos == 400):
            break

        # draws squares based on the JSON string
        if(rowList[c][r] == ' '):
            pygame.draw.rect(screen, White, (x_pos, y_pos, width, hight))

        #need to collide with these
        if(rowList[c][r] == 'X'):
            pygame.draw.rect(screen, Black, (x_pos, y_pos, width, hight))

        if(rowList[c][r] == 'A'):
            pygame.draw.rect(screen, Pink, (x_pos, y_pos, width, hight))
            if hasDrawn == False:
                CharacterSprite = pygame.image.load('playerSprite.png')
                CharacterSprite_x = x_pos
                CharacterSprite_y = y_pos
                perma_x = x_pos
                perma_y = y_pos
                screen.blit(CharacterSprite, (CharacterSprite_x, CharacterSprite_y))
                hasDrawn = True

        if(rowList[c][r] == 'B'):
            pygame.draw.rect(screen, Green, (x_pos, y_pos, width, hight))
            endPos = [x_pos, y_pos]


        x_pos += hight
        r += 1
        i += 1

这是网格绘图代码^,它根据JSON网格是“”(空),“ X”(墙),“ A”(起点)还是“ B”在屏幕上循环添加一个彩色框“(终点) 问题是我现在需要角色能够与黑色方块碰撞

如果有帮助,整个游戏板会在每次启动时随机生成。 代码中显示的矩形不是精灵,字符只是运动图像,不是类

我对PyGame还是很陌生,如果错过了一些重要的事情,对不起

游戏界面图片:

我尝试过的事情:

  • 如果角色试图移动到x1,y1,x2,y2坐标,但没有用,我尝试在绘制矩形的列表中“记住”并阻止移动,

  • 从我的抬头看,没有办法像感觉到的一样“感知”角色触摸的颜色,以这种方式阻止移动

1 个答案:

答案 0 :(得分:1)

您根本不需要进行几何碰撞测试。只需验证字符位置rowList中是否有'X'。如果玩家在狼牙棒中平稳移动,则角色的每个角都可以位于迷宫的不同区域。因此,您必须进行4次检查。

pygame.Surface的大小可以通过.get_size()获得:

cw, ch = CharacterSprite.get_size()

行和列的索引可以通过整数除法计算。以下cxcy是字符的位置:

corners = [(cx, cy), (cx+cw, cy), (cx+cw, cy+ch), (cx, cy+ch)]
corners_i = [(c[0] // width, c[1] // height) for c in corners]

使用any()来验证rowList中的任何元素是否为X

is_colliding = any([cr for cr in corners_i if rowList[cr[0]][cr[1]] == 'X'])

在移动之前存储字符的位置。如果发现冲突,请进行碰撞测试并重置角色的位置:

cur_cx, cur_cy = cx, cy
cw, ch = CharacterSprite.get_size()

# move the character and change cx/cy
# [...]

corners = [(cx, cy), (cx+cw, cy), (cx+cw, cy+ch), (cx, cy+ch)]
corners_i = [(c[0] // width, c[1] // height) for c in corners]
if any([cr for cr in corners_i if rowList[cr[0]][cr[1]] == 'X']):
    cx, cy = cur_cx, cur_cy