我正在用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_UP
或K_DOWN
键。如果是,则返回具有所需速度的新矢量,然后将其分配给paddle.body.velocity
。问题是,当桨到达屏幕的顶部或底部时,而不是停在那些坐标上,它会向上(或向下)进一步向上,直到释放相应的键,此时它会缓慢地返回到相反的位置。方向。该部分似乎对桨叶提供某种阻力,但只能设法将其停在屏幕中间。
为什么会这样? 如何限制球拍的移动,使其仅在周围区段建立的范围内移动?
答案 0 :(得分:2)
问题是你每帧直接在身体上设置速度。这将为碰撞求解器带来问题,并允许桨叶穿过墙壁。要么你改变它以便你施加冲动,要么用另一种方式限制它的运动。
我在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)
此处的完整代码: https://github.com/viblo/pymunk/blob/master/examples/breakout.py
请注意,每帧设置速度可能会产生其他副作用,但在您的情况下,我认为它应该可以正常工作,就像突破示例一样。
答案 1 :(得分:0)
一种解决方案是在桨到达顶部/底部墙时添加一些检测,如果命中,则限制速度仅允许在相反方向。
要做到这一点,你可以在墙和桨之间创建一个碰撞处理程序。然后在begin函数中在paddle上设置一个变量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.)