如何在Manim中实现弹性碰撞?现有代码无法让子弹反弹
在Manim中实现弹性碰撞的问题修复
问题根源
- 速度变量作用域错误:你在
updatebullet函数内部定义bullet_vel = 2,每次调用更新函数时,这个变量都会被重置为初始值2,导致修改速度的操作完全无效,下次更新又会回到原速度。 - 碰撞检测条件不准确:
square.get_x()是正方形的中心x坐标,子弹应该碰到正方形的左边缘(而非中心)才触发反弹,否则子弹会穿过正方形一部分才会有反应。
修正后的代码
class Problem2(Scene): def construct(self): square = Square(side_length=3) string = Line(square.get_corner(UP), [0, 4, 0], buff=0) bullet = Circle(radius=0.2, fill_color=GREY, fill_opacity=1) bullet.shift(6*LEFT) # 将速度绑定为bullet的属性,避免每次更新被重置 bullet.bullet_vel = 2 def updatebullet(bullet, dt): bullet.shift(bullet.bullet_vel * dt) # 检测子弹右边缘是否碰到正方形左边缘 if bullet.get_right()[0] >= square.get_left()[0]: bullet.bullet_vel = -bullet.bullet_vel # 可选:添加左边界检测,防止子弹飞出屏幕左侧后无法返回 # if bullet.get_left()[0] <= -6: # bullet.bullet_vel = -bullet.bullet_vel bullet.add_updater(updatebullet) self.play(FadeIn(square, string)) self.play(FadeIn(bullet)) self.wait(10)
关键修改说明
- 将速度变量
bullet_vel绑定为bullet对象的属性,这样每次更新时速度值会被保留,修改后不会被重置。 - 调整碰撞检测逻辑:判断子弹的右边缘是否触碰到正方形的左边缘,确保碰撞瞬间就触发反弹,符合真实物理碰撞的逻辑。
内容的提问来源于stack exchange,提问作者SirMrpirateroberts
相关产品推荐
相关产品推荐

