2

我正在用 pymunk 制作一个 pong 克隆,以了解 lib 的工作原理。我让球正确地从墙上反弹,但球拍仍然拒绝停留在由片段定义的矩形内,屏幕的每一侧都有一个。

def handle_input(self):
    keys = pygame.key.get_pressed()
    if keys[K_UP]: return Vec2d(0, 200)
    elif keys[K_DOWN]: return Vec2d(0, -200)
    else: return Vec2d(0, 0)

此功能检测是否按下K_UPK_DOWN键。如果是这样,它会返回一个具有所需速度的新向量,然后将其分配给paddle.body.velocity。问题是,当拨片到达屏幕的顶部或底部时,它不会在这些坐标上停下来,而是会稍微向上(或向下)移动,直到相应的键被释放,此时它会慢慢返回相反的方向方向。该部分似乎对桨提供了某种阻力,但只能设法将其停止在屏幕外的一半。

出去

为什么会这样?如何限制桨的运动,使其仅在周围部分确定的范围内移动?


来源game.py | 桨.py

4

2 回答 2

2

问题是您在每一帧都直接在身体上设置速度。这会给碰撞求解器带来问题,并允许桨叶穿过墙壁。要么你改变它以便你应用一个冲动,要么你以另一种方式限制它的运动。

我在 pymunk 的示例文件夹中也有一个类似的示例,breakout.py 在那里我使用了 GrooveJoint 来限制它的移动:

player_body = pymunk.Body(500, pymunk.inf)
player_shape = pymunk.Circle(player_body, 35)
player_shape.color = THECOLORS["red"]
player_shape.elasticity = 1.0
player_body.position = 300,100
# restrict movement of player to a straigt line 
move_joint = pymunk.GrooveJoint(space.static_body, player_body, (100,100), (500,100), (0,0))
space.add(player_body, player_shape, move_joint) 

完整代码在这里: https ://github.com/viblo/pymunk/blob/master/examples/breakout.py

请注意,每帧设置速度可能会产生其他副作用,但在您的情况下,我认为它应该可以正常工作,就像突破示例一样。

于 2014-11-22T07:07:37.667 回答
0

一种解决方案是在桨到达顶/底壁时添加一些检测,如果被击中,则将速度限制为仅允许在相反方向上。

为此,您可以在墙壁和桨之间创建一个碰撞处理程序。然后在开始函数中设置一个变量touch_top/touch_bottom 在桨上,并单独设置变量为false。

这是一个关于桨的基本示例,它使用这种技术在每一帧设置它的速度,直到它到达顶部:

import pymunk

space = pymunk.Space()

top = pymunk.Segment(space.static_body, (0,100), (100,100), 1)
space.add(top)
top.collision_type = 1

b = pymunk.Body(100,1000)
b.position = (50,50)
paddle = pymunk.Poly.create_box(b, (5,20))
paddle.collision_type = 2
space.add(b, paddle)

touching_top = False

def begin(space, arbiter, *args, **kwargs):
    global touching_top
    touching_top = True
    print "begin"
    return True

def separate(space, arbiter, *args, **kwargs):
    global touching_top
    touching_top = False
    print "separate"

space.add_collision_handler(1, 2, begin=begin, separate=separate)

for x in range(100):
    print paddle.body.position

    if not touching_top:
        paddle.body.velocity = (0,100)

    space.step(1/60.)
于 2014-11-25T13:11:35.527 回答