我想创建一个弹球游戏,但有时球不会与其他物体碰撞。 示例:https://youtu.be/HwSXwJ4-d2w
这是代码
import pyglet, pymunk
from pymunk.pyglet_util import DrawOptions
win = pyglet.window.Window(1280, 720, resizable=False)
options = DrawOptions()
space = pymunk.Space()
space.gravity = 0, -1000
def Ball(mass, radius, coords):
circle_moment = pymunk.moment_for_circle(mass, 0, radius)
circle_body = pymunk.Body(mass, circle_moment)
circle_shape = pymunk.Circle(circle_body, radius)
circle_shape.elasticity = 1.0
circle_body.position= coords
space.add(circle_body, circle_shape)
def BouncyCircle(mass, coords, radius):
circle_moment = pymunk.moment_for_circle(mass, 0, radius)
circle_body = pymunk.Body(mass, circle_moment, pymunk.Body.STATIC)
circle_shape = pymunk.Circle(circle_body, radius)
circle_shape.elasticity = 2.0
circle_body.position= coords
space.add(circle_body, circle_shape)
def Segment(mass, PointA, PointB, thickness):
segment_moment = pymunk.moment_for_segment(mass, PointA, PointB, thickness)
segment_body = pymunk.Body(mass, segment_moment, pymunk.Body.STATIC)
segment_shape = pymunk.Segment(segment_body, PointA, PointB, thickness)
segment_shape.elasticity = 0.7
segment_body.position = 0,0
space.add(segment_body, segment_shape)
Ball(0.1, 15, (640, 550)) #Falling Ball
BouncyCircle(1, (650,100), 40) #Ball
Segment(10, (105,55), (1195,55), 5) #Border
Segment(10, (100, 50), (100,680), 5)
Segment(10, (105, 675), (1195,675), 5)
Segment(10, (1200, 50), (1200, 680), 5)
@win.event
def on_draw():
win.clear()
space.debug_draw(options)
def update(dt):
space.step(dt)
if __name__ == "__main__":
pyglet.clock.schedule_interval(update, 1/60)
pyglet.app.run()
当它非常慢并且有时会反弹十次直到停止工作时,也会发生这种情况。有人知道如何解决吗?
答案 0 :(得分:0)
最有可能是因为球移动太快。如果在单个模拟步骤(对space.step()的调用)中,诸如球之类的物体从墙的一侧移到墙的另一侧,则球将穿过。
有几种方法可以缓解此问题。有时候,不只要做其中之一是个好主意。
确保对象的速度永远不会过高。一种方法是使用自定义速度函数,该函数内置了倾向于快速移动的物体的限制:
def limit_velocity(body, gravity, damping, dt):
max_velocity = 1000
pymunk.Body.update_velocity(body, gravity, damping, dt)
l = body.velocity.length
if l > max_velocity:
scale = max_velocity / l
body.velocity = body.velocity * scale
body_to_limit.velocity_func = limit_velocity
根据要求,将速度限制在多个帧上可能更有意义。然后极限功能可能看起来像这样:
def limit_velocity(body, gravity, damping, dt):
max_velocity = 1000
pymunk.Body.update_velocity(body, gravity, damping, dt)
if body.velocity.length > max_velocity:
body.velocity = body.velocity * 0.99
在对space.step的调用中为dt使用较小的值。一种简单的方法是在应用程序的每个帧中多次调用space.step。这也将有助于使整体模拟更加稳定。
我认为1或2是最适合您的选择。
我用以下说明更新了pymunk文档,并在此处进行了更多说明:http://www.pymunk.org/en/latest/overview.html#object-tunneling