2017-11-02 26 views
0

私は異なる速度値を設定する動的オブジェクトを持っています。しかし、この動的ボディが静的ボディに当たると、この衝突が解決されて後退するまで静的ボディと部分的に重なってしまいます。Pymunk:動的オブジェクトが静的オブジェクトに移動するのを防ぎます

pymunkには、速度がこの方向に適用されていても、静的ボディの境界に正確に停止する方法がありますか?衝突の競合がある場合は、2つの形状を重複させるよりも別の方法で解決することをお勧めします。

私は一定の速度を持ちたいので、力とインパルスを加えることは実際にはオプションではありません。そのそれ以来

(以下のコードは、作業に2回実行する必要があります。)一般的に

import pymunk 
import pyglet 
from PIL import Image 
from PIL import ImageDraw 

# setup of pyglet 

window = pyglet.window.Window() 
main_batch = pyglet.graphics.Batch() 
keys = pyglet.window.key.KeyStateHandler() 
window.push_handlers(keys) 

# setup of pymunk 

space = pymunk.Space() 

"""MOVABLE CIRCLE""" 

# creating pyglet sprite 

circle_img = Image.new('RGBA', (50,50)) 
draw = ImageDraw.Draw(circle_img) 
draw.ellipse((1, 1, 50-1, 50-1), fill=(255,0,0)) 
circle_img.save('circle.png') 
pyglet_circle_img = pyglet.resource.image('circle.png') 
pyglet_circle_img.anchor_x = pyglet_circle_img.width/2 
pyglet_circle_img.anchor_y = pyglet_circle_img.height/2 
circle_sprite = pyglet.sprite.Sprite(pyglet_circle_img, window.width/2, window.height/2, batch=main_batch) 

# creating pymunk body and shape 

mass = 2 
radius = 25 
moment = pymunk.moment_for_circle(mass, 0, radius) 
circle_body = pymunk.Body(mass, moment) 
circle_body.position = circle_sprite.position 
circle_shape = pymunk.Circle(circle_body, 25) 
circle_shape.elasticity = 0.0 
space.add(circle_body, circle_shape) 

"""STATIC SQUARE""" 

# creating pyglet sprite 

square_img = Image.new('RGBA', (70,70)) 
draw = ImageDraw.Draw(square_img) 
draw.rectangle([(0, 0), (70-1, 70-1)], fill=(0,255,0)) 
square_img.save('square.png') 
pyglet_square_img = pyglet.resource.image('square.png') 
pyglet_square_img.anchor_x = pyglet_square_img.width/2 
pyglet_square_img.anchor_y = pyglet_square_img.height/2 
square_sprite = pyglet.sprite.Sprite(pyglet_square_img, 3*window.width/4, window.height/2, batch=main_batch) 

# creating pymunk body and shape 

square_body = pymunk.Body(body_type=pymunk.Body.KINEMATIC) 
square_body.position = square_sprite.position 
square_shape = pymunk.Poly(square_body, [(-35,-35),(-35,35),(35,35),(35,-35)]) 
square_shape.elasticity = 0.0 
space.add(square_body, square_shape) 

def update(dt): 
    space.step(dt) 
    circle_sprite.position = circle_body.position 
    print(circle_body.position) 
    key_pressed = False 
    if keys[pyglet.window.key.LEFT]: 
     circle_body.velocity = (-100,0) 
     key_pressed = True 
    elif keys[pyglet.window.key.RIGHT]: 
     circle_body.velocity = (100, 0) 
     key_pressed = True 
    if keys[pyglet.window.key.UP]: 
     circle_body.velocity = (0, 100) 
     key_pressed = True 
    elif keys[pyglet.window.key.DOWN]: 
     circle_body.velocity = (0, -100) 
     key_pressed = True 
    if not key_pressed: 
     circle_body.velocity = (0,0) 

@window.event 
def on_draw(): 
    window.clear() 
    main_batch.draw() 

pyglet.clock.schedule_interval(update, 1/60.) 

pyglet.app.run() 

答えて

0

手動体の位置や速度を設定するときに奇妙な効果を期待するべきであると答えて、物理エンジンを騙す( 何かがテレポートされた場合、あなたが実際に奇妙な効果を得るのと同じように)

また、オブジェクトが衝突した場合、衝突がどのように解決されるかということも予想されます。スペースには、これを制御するために使用できる2つのプロパティ、collision_slopcollision_biasがあります。

しかし、いくつかの手作業による修正を試すことができます。 1つの方法は、衝突が起こるとオブジェクトを遠ざけることです。コリジョンコールバックでこれを行うことができます。ここで

あなたは重複を防ぐために、ちょうどあなたの例では、更新機能の前に置くことができる簡単な例です:

circle_shape.collision_type = 1 
h = space.add_wildcard_collision_handler(circle_shape.collision_type) 
def f(arbiter, space, data): 
    ps = arbiter.contact_point_set 
    arbiter.shapes[0].body.position += ps.normal * ps.points[0].distance 
h.post_solve = f 

(あなたの本当のコードであなたには、いくつかは、室内セーフティボックスが失敗し、また、より多くを占める追加する必要がありますより複雑な形をしている場合は1点)