【问题标题】:Pygame collidepoint() dont account for the blit()Pygame collidepoint() 不考虑 blit()
【发布时间】:2020-07-31 14:30:46
【问题描述】:

对不起,因为我是非英语人士,所以有任何语法错误

在隔离期间,我正在开发一款小游戏,并想制作一个地图制作工具,以加快关卡设计过程。 我的问题是,即使网格在屏幕上显示为我期望的那样,“getcollide”功能也不能解释表面的“blit”。我花了两天时间,想不出另一种方法来解决这个问题,这是一个示例代码:

    import pygame

    def run(l, h, fps, scene):
        pygame.init()
        ecran = pygame.display.set_mode((l, h))
        clock = pygame.time.Clock()

        scene_active = scene

        while scene_active != None:
            key = pygame.key.get_pressed()
            filtre_touche = []

            for event in pygame.event.get():
                close = False
                if event.type == pygame.QUIT:
                    close = True
                elif event.type == pygame.KEYDOWN:
                    alt = key[pygame.K_LALT] or touche_active[pygame.K_RALT]
                    if event.key == pygame.K_ESCAPE:
                        close = True
                    elif event.key == pygame.K_F4 and alt:
                        close = True
                if close :
                    scene.quit()
                else :
                    mouse_pos = pygame.mouse.get_pos()
                    filtre_touche.append(event)

            scene_active.traite_input(filtre_touche, key, mouse_pos)
            scene_active.update()
            scene_active.render(ecran)

            scene_active = scene_active.next

            pygame.display.flip()
            clock.tick(fps)

    surface = pygame.Surface((320,320))
    M = []
    for i in range(10):
        x = []
        for j in range(10):
            x.append(pygame.draw.rect(surface, (255,255,255),(i*32, j*32, 32,32), 1))
        M.append(x)
    print(M)

    class FirstScreen():
        def __init__(self):
            self.next = self
        def traite_input(self, evenement, touche, mouse_pos):
            for event in evenement :
                if event.type == pygame.KEYDOWN and event.key == pygame.K_RETURN:
                    pygame.quit()
            for line in M :
                for row in line:
                    if row.collidepoint(mouse_pos):
                        print('collide')

        def update (self):
            pass
        def render(self, ecran):
            ecran.fill((200,200,200))
            ecran.blit(surface, (350,250), surface.get_rect())

    run(800,600,60, FirstScreen())

如果您运行此程序,您将看到表面是我们期望的位置,而图块实际上是 32 x 32。但是将鼠标悬停在网格上没有任何效果。当您将鼠标悬停在网格应该在的位置时调用 print 语句,如果我在 0,0 处对表面进行了 blit。

我错过了什么吗?在搜索了这个网站、pygame doc和各种论坛之后,我似乎是唯一一个遇到这个问题的人,我做错了什么?

【问题讨论】:

    标签: python pygame grid collision blit


    【解决方案1】:

    这是因为你把网格放在一个表面上,在屏幕上对表面进行 bliting,所以当你制作网格时,你从表面的 0 开始。然后在执行collidepoint 时,在屏幕中间(ish)对表面进行blit。当接近 0 时,鼠标悬停在它上面,即整个屏幕的左上角。基本上,鼠标在窗口上的位置被转换到表面上,因此当您将鼠标悬停在网格上时,鼠标在窗口中的位置不在表面上的网格上。如果这有意义的话。

    简单修复:

    if row.collidepoint((mouse_pos[0] - 350,mouse_pos[1] - 250)):
    

    将鼠标向后移动,这样表面上的 0,0 就是窗口上的 0,0

    【讨论】:

    • 感谢您的回答! :) 所以在 blit 之后在表面上绘制的矩形不是“跟随”表面是正常行为吗?我觉得这有点奇怪,但至少我明白为什么我无法找到我的错误。谢谢 !既然你已经启发了我,Surfaces 似乎没那么有用了所以,在我的地图制作者的情况下,如果我想在屏幕左侧制作“选择瓷砖类型”的按钮,在中间制作一个网格放上瓷砖,我必须手动将所有坐标从屏幕转换为表面,并可能在 0,0 处破坏按钮?
    • 编辑:我知道我不会通过向后移动鼠标位置来“破坏”0,0 按钮,因为我只在这些特定行中寻找碰撞。但是您是否知道是否有一种方法可以知道表面的所有“孩子”以一次对所有表面应用修改而不是“硬代码”放大/缩小/位置编辑?
    • 不完全明白,但是,与其在表面上制作网格,然后将表面粘贴到屏幕上,不如在屏幕上制作网格,这将是最简单的方法。那么您不必担心转换鼠标位置。因为屏幕是一个表面
    • 而且,在曲面上绘制的矩形不跟随曲面,可以将其想象为在 Photoshop 中绘制一张图片,然后将该图片放入另一张图片中,其位置在第一张图片(本地)中保持不变,但是在第二张图片中,它的变化(全局)
    • 我在一个表面上绘图是为了在一个 10*10 的表面上制作一个 20*20 的网格,而不是显示整个网格,而是让它在表面内“可滚动”。用你的把 blit 减去鼠标位置的技巧应该是可能的,再次感谢 :) 对于基本界面,我现在将直接使用屏幕是的,它可以节省我一些按钮设置的时间 谢谢,我现在明白了使用 Photoshop 示例,我应该能够创建一个小函数,使用“surface.get_rect()”将“本地鼠标位置”中的“鼠标位置”转换回。再次感谢您的宝贵时间和快速答复
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-04
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多