Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/cmake/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python pymunk-如何限制移动?_Python_Pygame_Chipmunk_Pymunk - Fatal编程技术网

Python pymunk-如何限制移动?

Python pymunk-如何限制移动?,python,pygame,chipmunk,pymunk,Python,Pygame,Chipmunk,Pymunk,我正在用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) 此功能检测

我正在用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\u UP
K\u DOWN
键。如果是这样,它将返回一个具有所需速度的新向量,然后将该向量指定给
pable.body.velocity
。问题是,当拨片到达屏幕的顶部或底部时,它不会停在这些坐标上,而是向上(或向下)移动一点,直到释放相应的键,在这一点上,它会缓慢地以相反的方向返回。这段视频似乎对划桨产生了某种阻力,但只能在屏幕的一半位置阻止划桨

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



来源:|

问题在于,您直接在身体的每一帧上设置速度。这将给碰撞解算器带来问题,并允许挡板在墙中移动。要么你改变它,让它产生一种冲动,要么你用另一种方式限制它的运动

我在pymunk的examples文件夹中有一个类似的示例,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) 
完整代码如下:


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

一个解决方案是在桨叶到达顶部/底部墙壁时添加一些检测,如果击中,则限制速度仅允许在相反方向

为此,可以在墙和挡板之间创建碰撞处理程序。然后在begin函数中设置一个变量touching_top/touching_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.)

您可以发布与问题相关的其余代码吗?例如,在哪里设置分段,在哪里处理键盘处理程序的结果等。如果您还没有这样做,可能值得在花栗鼠论坛上发布一个指向此问题的链接。我尝试添加GrooveJoint,但没有成功。桨叶的移动超过了关节指定的坐标。或者这是预期的行为?您的代码和我的代码(从一开始我就没有看到)之间的区别是,您在按下键时设置速度,而我只在按下键时设置速度。这就是为什么在我的例子中效果更好。请参阅我的另一个答案,了解不同的解决方案。你能举个例子说明如何做到这一点吗?