Pygame碰撞代码

use*_*048 5 python pygame pymunk

首先,我必须说我是法国人(这样你就明白为什么我会犯所有这些错误,哈哈)

\n\n

我正在使用 python、pygame 和 pymunk 开发一个物理游戏:一个球(我称之为 X)必须到达 Y 点。这是一款 2d 平台游戏。为了帮助球到达 Y 点,用户必须添加球(右键单击)并制作形状来帮助 X 移动。

\n\n

但是......当我发现(最近,在我开始编码之后)pygame 中类和方法以及精灵的存在时,我很惊讶地发现我的代码“丑陋”,而且太混乱了。但我不想重写代码,我的目标是在“空间”(窗口)中添加一个区域,当 X 与其碰撞时,会发生一个事件(例如;下一个级别,出现一张图片) , ETC)。

\n\n

谁能帮我 ?我一直在法国论坛上询问,但找不到解决方案。我希望堆栈溢出社区能够解决这个问题^^

\n\n

谢谢大家 :)

\n\n

(代码:)

\n\n
    import pygame\nfrom pygame.locals import *\nfrom pygame.color import *\n\nimport random\nimport math\nimport pymunk\nfrom pymunk import Vec2d\nimport pymunk as pm\n\nX,Y = 0,1\n### Physics collision types\nCOLLTYPE_DEFAULT = 0\nCOLLTYPE_MOUSE = 1\nCOLLTYPE_BALL = 2\n\n\ndef flipy(y):\n    """Small hack to convert chipmunk physics to pygame coordinates"""\n    return -y+600\n\n\ndef mouse_coll_func(space,arbiter):\n    s1,s2 = arbiter.shapes\n    s2.unsafe_set_radius(s2.radius + 0.15)\n    return False\n\ndef main():\n\npygame.init()\n\nfen1 = pygame.display.set_mode((1200, 675))\npygame.display.set_caption(\'Niveau 1\')\n\n\n\nmarche = True\n\n#Elements physiques\nspace = pm.Space()\nspace.gravity = Vec2d(0.0, -900.0)\nclock = pygame.time.Clock()\n\n#Balles\nlogos = []\nlogo_img = pygame.image.load("pringles.png").convert_alpha()\nballs = []\nball_static = []\n\n\n###Mouvements \xc3\xa0 la souris\nmouse_body = pm.Body()\nmouse_shape = pm.Circle(mouse_body, 3, Vec2d(99,99)) #0,0\nmouse_shape.collision_type = COLLTYPE_MOUSE\nspace.add(mouse_shape)\n\nspace.add_collision_handler(COLLTYPE_MOUSE, COLLTYPE_BALL, None, mouse_coll_func, None, None)   \n\n# Static line\nstatic_body = pymunk.Body()\nstatic_lines = [pymunk.Segment(static_body, (139.0, 480.0), (137.0, 479.0), 0.0)\n               ,pymunk.Segment(static_body, (18.0, 497.0),  (249.0, 496.0), 0.0)\n               ,pymunk.Segment(static_body, (252.0, 496.0), (309.0, 479.0), 0.0)\n               ,pymunk.Segment(static_body, (309.0, 477.0), (358.0, 443.0), 0.0)\n               ,pymunk.Segment(static_body, (358.0, 443.0), (407.0, 374.0), 0.0)\n               ,pymunk.Segment(static_body, (407.0, 374.0), (433.0, 287.0), 0.0)\n               ,pymunk.Segment(static_body, (482.0, 79.0),  (520.0, 34.0), 0.0)\n\n               ,pymunk.Segment(static_body, (433.0, 287.0), (449.0, 193.0), 0.0)\n               ,pymunk.Segment(static_body, (450.0, 193.0), (458.0, 130.0), 0.0)\n               ,pymunk.Segment(static_body, (458.0, 130.0), (480.0, 79.0), 0.0)\n               ,pymunk.Segment(static_body, (521.0, 34.0),  (573.0, 8.0), 0.0)\n               ,pymunk.Segment(static_body, (573.0, 8.0), (645.0, -12.0), 0.0)\n\n               ,pymunk.Segment(static_body, (645.0, -12.0), (714.0, -17.0), 0.0)\n               ,pymunk.Segment(static_body, (714.0, -17.0), (805.0, -15.0), 0.0)\n               ,pymunk.Segment(static_body, (805.0, -15.0), (889.0, -6.0), 0.0)\n               ,pymunk.Segment(static_body, (890.0, -5.0), (995.0, 13.0), 0.0)\n               ,pymunk.Segment(static_body, (995.0, 13.0), (1077.0, 23.0), 0.0)\n               ,pymunk.Segment(static_body, (1077.0, 23.0), (1199.0, 24.0), 0.0)\n               ,pymunk.Segment(static_body, (18.0, 497.0), (0.0, 515.0), 0.0)          \n               ,pymunk.Segment(static_body, (1197.0, 598.0), (1197.0, -71.0), 0.0)]\n\n#apparition de GES\nrt = 200, 502\nbodyrt = pm.Body(20, 100)\nbodyrt.position = rt\nshapert = pm.Circle(bodyrt, 40, (0,0))\nshapert.friction = 90\nshapert.collision_type = COLLTYPE_BALL\nspace.add(bodyrt, shapert)\n#image = pygame.image.load("perso.png").convert_alpha()\nball_static.append(shapert)\n\n\n\n# Static line\nline_point1 = None\n#static_lines = []\nrun_physics = True\n\n###Friction avec les lignes \nfor l in static_lines:\n    l.friction = 0.5\nspace.add(static_lines)\n\n#Fonctions \xc3\xa0 la souris \nwhile marche:\n    for event in pygame.event.get():\n        if event.type == QUIT:\n            marche = False\n        elif event.type == KEYDOWN and event.key == K_ESCAPE:\n            marche = False\n        elif event.type == KEYDOWN and event.key == K_p:\n            pygame.image.save(fen1, "test_image.jpg")\n\n\n        elif event.type == MOUSEBUTTONDOWN and event.button == 1:\n            p = event.pos[X], flipy(event.pos[Y])\n            body = pm.Body(20, 100)\n            body.position = p\n            shape = pm.Circle(body, 20, (0,0))\n            shape.friction = 90\n            shape.collision_type = COLLTYPE_BALL\n            space.add(body, shape)\n            balls.append(shape)\n\n\n        elif event.type == MOUSEBUTTONDOWN and event.button == 3: \n            if line_point1 is None:\n                line_point1 = Vec2d(event.pos[X], flipy(event.pos[Y]))\n        elif event.type == MOUSEBUTTONUP and event.button == 3: \n            if line_point1 is not None:\n\n                line_point2 = Vec2d(event.pos[X], flipy(event.pos[Y]))\n                print (line_point1, line_point2)\n                body = pm.Body()\n                shape= pm.Segment(body, line_point1, line_point2, 0.0)\n                shape.friction = 0.99\n                space.add(shape)\n                static_lines.append(shape)\n                line_point1 = None\n\n        elif event.type == KEYDOWN and event.key == K_SPACE:    \n            run_physics = not run_physics\n\n\n    p = pygame.mouse.get_pos()\n    mouse_pos = Vec2d(p[X],flipy(p[Y]))\n    mouse_body.position = mouse_pos\n\n\n\n\n    #mise \xc3\xa0 jour\n    dt = 1.0/60.0\n    for x in range(1):\n        space.step(dt)\n\n    #################################################\n\n\n    ### Dessiner fond\n\n    fond1=pygame.image.load("niveau_1.gif")\n    pygame.display.flip()\n    fen1.blit(fond1, (0,0))\n\n    for ball in balls:           \n        r = ball.radius\n        v = ball.body.position\n        rot = ball.body.rotation_vector\n        p = int(v.x), int(flipy(v.y))\n        p2 = Vec2d(rot.x, -rot.y) * r * 0.9\n        pygame.draw.circle(fen1, THECOLORS["blue"], p, int(r), 2)\n        pygame.draw.line(fen1, THECOLORS["yellow"], p, p+p2)\n        pe = pygame.image.load("pringles.png")\n        pf = pygame.image.load("pringles3.png")\n        fen1.blit(pe, (p2,v))  #essayer p2,v\n        #fen1.blit(pf, (p, p2))\n\n        ####\n\n    for ball in ball_static:           \n        r = ball.radius\n        v = ball.body.position\n        rot = ball.body.rotation_vector\n        p = int(v.x), int(flipy(v.y))\n        pt = int(v.x), int(flipy(v.y)) -90\n        p2 = Vec2d(rot.x, -rot.y) * r * 0.9\n        fdr = pygame.image.load("pringles2.png")\n        pygame.draw.circle(fen1, THECOLORS["yellow"], p, int(r), 2)\n        pygame.draw.line(fen1, THECOLORS["red"], p, p+p2)\n        fen1.blit(fdr,(pt,pt))\n\n    #   ESSAI\n    if pygame.collide_rect(static_ball, static_lines):\n        print (\'....\')\n\n            ###\n\n    if line_point1 is not None:\n        p1 = line_point1.x, flipy(line_point1.y)\n        p2 = mouse_pos.x, flipy(mouse_pos.y)\n        pygame.draw.lines(fen1, THECOLORS["black"], False, [p1,p2])\n\n    for line in static_lines:\n        body = line.body\n\n        pv1 = body.position + line.a.rotated(body.angle)\n        pv2 = body.position + line.b.rotated(body.angle)\n        p1 = pv1.x, flipy(pv1.y)\n        p2 = pv2.x, flipy(pv2.y)\n        pygame.draw.lines(fen1, THECOLORS["lightgray"], False, [p1,p2])\n        ##########################################################\n\n\n\n\n\n\n\n\n\n  if __name__ == \'__main__\':\n      main()\n
Run Code Online (Sandbox Code Playgroud)\n

tre*_*kby 0

据我了解,您需要知道精灵是否发生碰撞,然后如果发生碰撞,您就想做点什么。Pygame 有 spritecollide 函数。这是一个包装函数,它使它变得更容易一些,如果两个精灵发生碰撞,它将返回 True。

def collides(sprite1,sprite2):
    sprite1_group = pygame.sprite.RenderUpdates()    #this creates a render updates group, as the sprite collide function requires one of its arguments to be a group.
    sprite1_group.add(sprite1)
    collisions = pygame.sprite.spritecollide(sprite2, sprite1_group, False)  #runs spritecollide, specifying the sprite, the group, and the last parameter, which should almost always be false.
    for other in collisions:
        if other != sprite2:     #spritecollide registers a sprites collision with itself, so this filters it
            return True
Run Code Online (Sandbox Code Playgroud)

现在你有了一个可以检测碰撞的函数,如下所示:

if collides(sprite1,sprite2)
Run Code Online (Sandbox Code Playgroud)

如果您需要在不中断常规代码的情况下处理此事件,则始终可以使用线程。