如何在3D导入的波前OBJ文件上实现对象碰撞

时间:2019-07-10 16:51:20

标签: python pygame pyopengl opengl-compat

我正在pyGame中制作3D迷宫游戏,并在OBJ文件中创建环境,并使用pyGame网站上的OBJFileLoader将其加载到我的游戏中。但是当我实现运动控制时,相机会通过模型。如何检测相机和模型之间的碰撞,以便修复该问题?

我考虑过使用矩形碰撞检测,但是我能找到的所有实现都是2D的,很难用3D来实现,而且使用obj文件并没有使它更容易。我还在某个地方读到可以使用光线追踪的内容,但是找不到与在pyGame中使用光线投射有关的任何内容。

下面是我在主循环中用于控制游戏中移动的代码

while 1:
    for event in pygame.event.get():
        if event.type == QUIT:
            sys.exit()
        if event.type == KEYUP and event.key == K_ESCAPE:
            sys.exit()

    time_passed = clock.tick()
    time_passed_seconds = time_passed / 1000.

    glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT)
    glLoadIdentity()

    pressed = pygame.key.get_pressed()

    rotation_direction.set(0.0, 0.0, 0.0)
    movement_direction.set(0.0, 0.0, 0.0)

    if pressed[K_a]:
        rotation_direction.y = +1.0
    elif pressed[K_d]:
        rotation_direction.y = -1.0
    if pressed[K_w]:
        movement_direction.z = -1.0
    elif pressed[K_s]:
        movement_direction.z = +1.0

    # Calculate rotation matrix and multiply by camera matrix
    rotation = rotation_direction * rotation_speed * time_passed_seconds
    rotation_matrix = Matrix44.xyz_rotation(*rotation)
    camera_matrix *= rotation_matrix

    # Calcluate movment and add it to camera matrix translate
    heading = Vector3(camera_matrix.forward)
    movement = heading * movement_direction.z * movement_speed
    camera_matrix.translate += movement * time_passed_seconds

    # Upload the inverse camera matrix to OpenGL
    glLoadMatrixd(camera_matrix.get_inverse().to_opengl())

    glCallList(obj.gl_list)

    pygame.display.flip()

对于如何真正阻止用户穿过墙壁移动,我感到非常困惑,我需要这样做才能使我制作的迷宫游戏真正起作用。

1 个答案:

答案 0 :(得分:1)

通常来说,使用3D几何网格作为碰撞检测数据并不是一个好主意。通常,我们这样做的方法是拥有一个更简单的碰撞几何(理想情况下,它们由简单的图元组成,例如盒子,圆柱体,球体,平面-尽管在某些情况下可以使用三重网格)。然后,通常将播放器/相机表示为胶囊,然后针对几何形状测试胶囊。在 REALLY 中很难实现这种形式的3D碰撞检测。

如果可以将迷宫游戏简化为2D问题(例如,俯视图),则定义一组定义迷宫轮廓的2D线,并处理玩家/相机圈。

即使2D场景也很困难。最佳系统将需要解决联立方程的负载,以便确定最接近的交点。随着迷宫大小的增加,解决此问题的复杂性变得非常令人不适(即,您需要使用某种形式的空间分区,例如BSP树,四叉树等)

这是一个非常棘手的问题,这就是为什么大多数理智的人会简单地使用物理引擎来为他们执行这些计算。我可能会建议您先尝试使用简单的2D物理引擎,例如Box2D。如果您绝对需要3D碰撞检测,那么您可能希望查看PhysX,Bullet或Havok。