【问题标题】:Colliding shapes in pythonpython中的碰撞形状
【发布时间】:2015-11-25 21:02:22
【问题描述】:

我的计划是创建一个“简单”的 2 人迷你游戏(例如相扑和比赛)。

我的目标是有效地实现碰撞(我当前的代码只能处理简单的墙壁物理和对象的移动)与可以是环境的任何一部分的方形、圆形(和三角形?)形状的对象(例如. “岩石”或不可移动的障碍物)或部分用户控制的物品(例如“汽车”或可推动的障碍物)。也很高兴知道如何在碰撞中解释质量。

有两个方面我需要帮助:

  1. 两个移动物体(具有质量和二维矢量)之间不同类型的动态碰撞 (物理部分不是检测)。

  2. 确保所有需要碰撞的东西都足够快地碰撞(这样我的慢速计算机仍然可以每秒渲染超过 40-60 帧),并根据特定规则(或者如果可能的话)根据一条规则?)。这样管理需要碰撞的对象(添加、删除、修改等)也不会很困难。

或者我应该只为 ex 实现两种类型的碰撞。静态+动态圈和动态+动态圈?

def checkcollisions(object1, object2):
    # x is the current x position
    # y is the current y position
    # angle is the current vector angle (calculated from x and y with pythagoros
    # speed is the length of the vector
    dx = object1.x - object2.x
    dy = object1.y - object2.y

    dist = hypot(dx, dy)
    if dist < object1.radius + object2.radius:
        angle = atan2(dy, dx) + 0.5 * pi
        total_mass = object1.mass + object2.mass
        '''''http://www.petercollingridge.co.uk/pygame-physics-simulation/mass'''''
        if (0.79 <= object1.angle < 2.36 or 0.79-2*pi <= object1.angle < 2.36-2*pi) or (3.93 <= object1.angle < 5.5 or 3.93-2*pi <= object1.angle < 5.5-2*pi) and ((0.79 <= object2.angle < 2.36 or 0.79-2*pi <= object2.angle < 2.36-2*pi) or (3.93 <= object2.angle < 5.5 or 3.93-2*pi <= object2.angle < 5.5-2*pi)):
            (object2angle, object2speed) = vectorsum((object2.angle, object2.speed*(object2.mass-object1.mass)/total_mass), (angle+pi, 2*object1.speed*object1.mass/total_mass))
            (object1angle, object1speed) = vectorsum((object1.angle, object1.speed*(object1.mass-object2.mass)/total_mass), (angle, 2*object2.speed*object2.mass/total_mass))
        else:
            '''''https://en.wikipedia.org/wiki/Elastic_collision'''''
            CONTACT_ANGLE = angle
            x = (((object1.speed * cos(object1.angle - CONTACT_ANGLE) * (object1.mass-object2.mass)+ 2*object2.mass*object2.speed*cos(object2.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object1.speed*sin(object1.angle - CONTACT_ANGLE)*cos(CONTACT_ANGLE + 0.5 * pi)
            y = (((object1.speed * cos(object1.angle - CONTACT_ANGLE) * (object1.mass-object2.mass)+ 2*object2.mass*object2.speed*cos(object2.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object1.speed*sin(object1.angle - CONTACT_ANGLE)*sin(CONTACT_ANGLE + 0.5 * pi)
            object1angle = pi/2 - atan2(y, x)
            object1speed = hypot(x, y)

            x = (((object2.speed * cos(object2.angle - CONTACT_ANGLE)*(object2.mass-object1.mass)+2*object1.mass*object1.speed*cos(object1.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object2.speed*sin(object2.angle - CONTACT_ANGLE)*cos(CONTACT_ANGLE + 0.5 * pi)
            y = (((object2.speed * cos(object2.angle - CONTACT_ANGLE)*(object2.mass-object1.mass)+2*object1.mass*object1.speed*cos(object1.angle - CONTACT_ANGLE))/total_mass)*cos(CONTACT_ANGLE))+object2.speed*sin(object2.angle - CONTACT_ANGLE)*sin(CONTACT_ANGLE + 0.5 * pi)
            object2angle = pi/2 - atan2(y, x)
            object2speed = hypot(x, y)

        (object2.angle, object2.speed) = (object2angle, object2speed)
        (object1.angle, object1.speed) = (object1angle, object1speed)
        object1.speed *= 0.999
        object2.speed *= 0.999

        overlap = 0.5*(object1.radius + object2.radius - dist+1)
        object1.x += sin(angle)*overlap
        object1.y -= cos(angle)*overlap
        object2.x -= sin(angle)*overlap
        object2.y += cos(angle)*overlap

'''''http://www.petercollingridge.co.uk/pygame-physics-simulation/mass'''''


def vectorsum(vectorx, vectory):  # Every array's first number is the degree from 0, the second is speed
    x = sin(vectory[0]) * vectory[1] + sin(vectorx[0]) * vectorx[1]
    y = cos(vectory[0]) * vectory[1] + cos(vectorx[0]) * vectorx[1]  # Calculating new vectors from anle and lenght
    angle = pi / 2 - atan2(y, x)  # Calculating the degree
    speed = hypot(x, y)  # Calculating the speed
    return angle, speed

(我只是 Python(或英语)的初学者,请记住这一点。)

【问题讨论】:

    标签: python python-3.x game-physics physics-engine


    【解决方案1】:
    1. pygame 中的碰撞检测非常简单。看看使用pygame.sprite。它们具有多种检测碰撞的功能。 (spritecollidegroupcollide 等)如果您有一些复杂的碰撞交互,通常您使用矩形或圆形来查看它们是否碰撞,然后只对这些进行复杂的计算。尽管对于大多数游戏来说,您不需要为完美的碰撞检测付出代价,但足够接近就足够了。
    2. 就碰撞时发生的情况而言,更多的是物理而不是编程。要记住的一些概念是:动量守恒、弹性与非弹性碰撞、偏转角。 “如何构建 2D 物理引擎”对于 SO 问题来说有点过于宽泛。也许看看how-to-create-a-custom-2d-physics-engine-oriented-rigid-bodies

    【讨论】:

    • 确实碰撞检测很容易,但碰撞部分本身并没有加上迭代我将拥有的所有对象会太慢(在慢速计算机上)。这就是我需要帮助的地方,我会尽量让我的问题更清楚。
    • @Avamander 我认为更多细节在这里会很好。有多少个可碰撞的物体?有多少人可能同时搬家?您要模拟哪种类型的碰撞?不同的可碰撞物体在被撞击时应该如何表现?
    • 1-50(最多 100 个)对象。一半的物体会同时移动。我正在尝试模拟弹性碰撞。物体应该根据它们的质量和速度尽可能真实地碰撞(我怀疑大小是否重要)。基本上,en.wikipedia.org/wiki/Elastic_collision,但在 python 中,不仅有圆圈。我还发布了我设法与两个圈子合作的当前方式。
    • 当前代码很可怕,但一半(教程代码)适用于侧面的碰撞,另一半(维基百科公式)适用于顶部和底部的碰撞。公式有点太复杂,我无法修复或查找错误,并且当前函数不关心正方形和三角形。
    • 有什么想法可以改进我现有的代码或创建更好的代码吗?
    猜你喜欢
    • 2016-08-24
    • 1970-01-01
    • 2021-12-18
    • 2023-03-16
    • 1970-01-01
    • 2012-07-07
    相关资源
    最近更新 更多