2014-11-21 79 views
1

我正在与pymunk一个傍克隆为了学习如何的lib作品。我把球从墙上正确地弹起,但桨仍然拒绝留在由线段定义的矩形内,屏幕的每一侧都有一个。pymunk - 如何限制移动?

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。问题是,当桨叶达到的,而不是暂停对这些坐标在屏幕的顶部或底部,它进入一点点进一步向上(或向下),直到相应的键被释放,在该点它慢慢在相反的返回方向。该部分似乎对桨提供了某种阻力,但只能在屏幕中途停下。

out

这究竟是为什么? 我怎样才能限制桨的运动,使其只能通过周围段建立的范围内移动?


来源game.py | paddle.py

+0

您可以发布,是有关该问题的代码的其他人呢?例如。在那里你设置段,你在哪里处理键盘处理器的结果等。 – 2014-11-21 10:53:54

+0

如果你还没有这样做,可能值得在chipmunk论坛上发布这个问题的链接。 – 2014-11-21 15:59:22

回答

1

的问题是,可以直接在所述主体的每个帧中设置的速度。这将为碰撞解算器带来问题,并允许桨板穿过墙壁。要么你改变它,以便你改用冲动,或者以另一种方式限制它的移动。

我在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

注意,设置每一帧的速度可能有其他副作用,但在你的情况下,我认为它应该工作得很好,就像突破的例子。

+0

我尝试添加GrooveJoint,但它没有奏效。桨比联合指定的坐标更进一步移动。或者这是预期的行为? – Jovito 2014-11-22 07:33:02

+0

你的代码和我的代码(我从一开始就没有看到)之间的区别在于你在按下按键时设置了速度,而我只在按下按键时设置了它。这就是为什么它在我的例子中效果更好。请参阅我的其他答案以获取其他解决方案 – viblo 2014-11-25 13:13:26

0

一种解决方案是增加一些检测当该桨叶到达顶/底壁,并且如果击中限制速度为仅在相反方向上被允许。

要做到这一点,你可以创建墙壁和桨之间的冲突处理。然后在begin函数中设置一个变量touches_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.) 
+0

你能举一个例子来说明如何做到这一点吗? – Jovito 2014-12-01 08:32:04

+0

我用一个例子更新了答案 – viblo 2014-12-05 07:19:56