针对地图中的播放器和块的碰撞检测

2024-04-18 09:32:01 发布

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

我做了一张这样的游戏地图

class Game_map:
    def __init__(self):
        self.land = pygame.image.load(r"C:\Users\name\OneDrive\Documents\A level python codes\final game\land.png").convert()
        self.height = 200
        self.width = 200
        self.land = pygame.transform.scale(self.land, (420,  250))
        self.land.set_colorkey((0, 0, 0))

        self.map_width = 6000
        self.map_height = 2000

        # 0 = emepty
        # 1 = land

        self.layout = [[ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 1, 1, 1, 1, 0 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 0, 0, 1, 1, 1, 0, 0, 0, 1, 1, 0, 0, 0, 0, 1 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [ 1, 0, 0, 1, 1, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0 ],
                              [ 0, 1, 0, 0, 0, 0, 1, 1, 1, 0, 0, 0, 0, 0, 0 ],
                              [ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 ],
                              [0, 0, 0, 1, 0, 0, 1, 0, 0, 0, 1, 1, 0, 0, 0 ]]



    def draw_map(self):
        y = 0
        for layer in self.layout:
            x = 0
            for land in layer:
                if land == 1:
                    D.blit(self.land, (x * 400 - scroll[0],  y * 250 - scroll[1]))

                if land == 0:
                    pass

                x += 1
            y += 1




game_map = Game_map()

我还有一个player类self.xself.yself.widthself.height。我将如何使用此工具实现碰撞检测?我最初的想法是,我将在draw_map()函数中使用self.xself.y,以便以后可以检查这样的冲突

 def draw_map(self):
        for layer in self.layout:
            for land in layer:
                if land == 1:
                    D.blit(self.land, (self.x * 400 - scroll[0], self. y * 250 - scroll[1]))

                if land == 0:
                    pass

                x += 1
            y += 1

但是当我这样做的时候,屏幕上什么也没有画出来。我还尝试将上面提到的原始draw_map函数中的xy值添加到一个列表中,并检测与该值的冲突,但它变得非常混乱,无法工作。是否有其他方法进行碰撞检测?谢谢


Tags: inselflayergamemapforifdef
1条回答
网友
1楼 · 发布于 2024-04-18 09:32:01

直接的方法是找到玩家矩形和障碍矩形的碰撞

创建所有障碍物的现场索引列表:

obstacles = [(i, j) for i in range(len(game_map.layout))
                    for j in range(len(game_map.layout[i]))
                    if game_map.layout[i][j] == 1]

为播放器设置一个^{}

player_rect = pygame.Rect(player.x, player.y, player.width, player.height) 

使用^{}查找玩家和障碍物的碰撞:

hit = [obj for obj in obstacles
           if player_rect.colliderect(
               pygame.Rect(obj[0]*400-scroll[0], obj[1]*250-scroll[1], 400, 250))]

if any(hit):
    print("hit")

更复杂、更有效的方法是计算玩家矩形的4个角的场指数,并评估其中一个角是否位于有障碍物的场中

设置播放器矩形:

player_rect = pygame.Rect(player.x, player.y, player.width, player.height) 

计算矩形角点的坐标:

player_corners = [player_rect.topleft, player_rect.topright, 
                  player_rect.bottomleft, player_rect.bottomright]

计算场索引,其中角点位于:

corner_indices = [((p[0]+scroll[0])//400, (p[1]+scroll[1])//250) for p in player_corners]

评估任何字段是否包含障碍物:

hit = [ind for ind in corner_indices if game_map.layout[ind[0]][ind[1]]]

if (any(hit)):
    print("hit")

相关问题 更多 >