当前位置: 首页 > 面试题库 >

如何设置SceneKit碰撞检测

王高超
2023-03-14
问题内容

您好,我已经仔细阅读了文档,无法弄清楚如何在场景工具包中设置碰撞检测。可以请一个例子。请帮我,我非常渴望解决这个问题。谢谢!

编辑:您好,非常感谢,对不起,我忘了提及我的项目进展迅速。没什么大不了的,我大部分时间都可以自我翻译。

当对象碰撞并相互反弹时,我使BitMasks正常工作。但是我似乎无法使该功能正常工作

func physicsWorld(world: SCNPhysicsWorld, didBeginContact contact: SCNPhysicsContact){
    let contactMask = contact.nodeA.physicsBody!.categoryBitMask | contact.nodeB.physicsBody!.categoryBitMask
    if (contactMask == (CollisionBallCategory | CollisionTerminatorCategory)) {
        println("Collided")
    }
}

查看文档,看来我需要以某种方式将场景物理世界委托分配给该方法。我不确定该怎么做。


问题答案:

在SceneKit中获得碰撞检测的主要内容:

  • 它基于位掩码,它们一起构成了一个表。
  • 联系人代表就是您如何应对冲突。

使物体碰撞

例如,您可能会用简单的英语陈述游戏设计,如下所示:

小行星互相撞击(并形成较小的小行星)。导弹应该相互穿过,但要摧毁火箭和小行星。火箭不应该对导弹做任何事情(反之亦然),但是如果一个火箭与另一个火箭或小行星之间的距离太近,那么您将面临一个严重问题,并且您今天将不会进入太空。

通过碰撞检测来实现这一目标的第一步是根据哪些对之间的相互作用来整理该设计。您可以使用表格进行此操作:

         | Missile | Rocket | Asteroid
--------------------------------------
Missile  | No      | Yes    | Yes
Rocket   | No      | Yes    | Yes
Asteroid | No      | No     | Yes

然后,您可以将表的标题转换为一组类别常量,以供您在代码中使用。

typedef NS_OPTIONS(NSUInteger, CollisionCategory) {
    CollisionCategoryMissile    = 1 << 0,
    CollisionCategoryRocket     = 1 << 1,
    CollisionCategoryAsteroid   = 1 << 2,
};

missile.physicsBody.categoryBitMask = CollisionCategoryMissile;
rocket.physicsBody.categoryBitMask = CollisionCategoryRocket;
asteroid.physicsBody.categoryBitMask = CollisionCategoryAsteroid;

在这些常量上使用按位或运算符创建collisionBitMask填充表中的值。

missile.physicsBody.collisionBitMask =
    CollisionCategoryRocket | CollisionCategoryAsteroid;
rocket.physicsBody.collisionBitMask =
    CollisionCategoryRocket | CollisionCategoryAsteroid;
asteroid.physicsBody.collisionBitMask = CollisionCategoryAsteroid;

这就是使SceneKit为您解决冲突(即使对象相互反弹)所需要的。

应对碰撞

如果您还希望收到碰撞通知(因此您可以使导弹炸毁,并使飞船驶向小行星终点),则需要在场景的物理世界上设置联系人代表并实施一个或多个发生联系人时调用的联系人委托方法的一部分。

在您的联系人委托方法(例如physicsWorld:didBeginContact:)中,您需要找出联系人所涉及的主体类别,以及哪些类别,因此您可以获取执行碰撞操作的代码:

- (void)physicsWorld:(SCNPhysicsWorld *)world didBeginContact:(SCNPhysicsContact *)contact
{
    CollisionCategory contactMask =
        contact.nodeA.physicsBody.categoryBitMask | contact.nodeB.physicsBody.categoryBitMask;

    // first, sort out what kind of collision
    if (contactMask == (CollisionCategoryMissile | CollisionCategoryRocket)) {
        // next, sort out which body is the missile and which is the rocket
        // and do something about it
        if (contact.nodeA.physicsBody.categoryBitMask == CollisionCategoryMissile) {
            [self hitRocket:contact.nodeB withMissile:contact.nodeA];
        } else {
            [self hitRocket:contact.nodeA withMissile:contact.nodeB];
        }
    } else if (contactMask == (CollisionCategoryMissile | CollisionCategoryAsteroid)) {
        // ... and so on ...
    }
}

将此代码放在您的一个类中(可能是一个视图控制器,可能在您保持游戏逻辑良好的任何地方),并使该类声明符合SCNPhysicsContactDelegate协议。

@interface ViewController: UIViewController <SCNPhysicsContactDelegate>

然后将该对象分配给场景的物理世界,作为联系人代表:

// in initial setup, where presumably you already have a reference to your scene
scene.physicsWorld.contactDelegate = self

了解更多

SCNPhysicsBody参考文档中有一些有关冲突解决的内容。苹果公司提供了一些使用碰撞检测的示例代码-
这是WWDC
幻灯片,演示示例应用程序以及汽车物理演示中演示的一部分。

除此之外,SceneKit的碰撞处理模型与SpriteKit几乎完全相同,因此SpriteKit编程指南中的几乎所有内容对于理解SceneKit中的相同内容也很有用。



 类似资料:
  • 碰撞检测 现在你知道了如何制造种类繁多的图形对象,但是你能用他们做什么?一个有趣的事情是利用它制作一个简单的 碰撞检测系统 。你可以用一个叫做:hitTestRectangle 的自定义的函数来检测两个矩形精灵是否接触。 hitTestRectangle(spriteOne, spriteTwo) 如果它们重叠, hitTestRectangle 会返回 true。你可以用 hitTestRect

  • 本节暂未进行完全的重写,错误可能会很多。如果可能的话,请对照原文进行阅读。如果有报告本节的错误,将会延迟至重写之后进行处理。 当试图判断两个物体之间是否有碰撞发生时,我们通常不使用物体本身的数据,因为这些物体常常会很复杂,这将导致碰撞检测变得很复杂。正因这一点,使用重叠在物体上的更简单的外形(通常有较简单明确的数学定义)来进行碰撞检测成为常用的方法。我们基于这些简单的外形来检测碰撞,这样代码会变得

  • 问题内容: 有人可以帮我了解JS中冲突检测的工作原理吗?我不能使用jQuery或gameQuery-已经使用了原型- 因此,我正在寻找非常简单的东西。不要求完整的解决方案,只需为我指明正确的方向。 假设有: 现在球正在移动(任何方向)。“ Someobject”(0-X)已经预先定义,其中有20-60个随机放置,如下所示: 我可以创建一个位置为“ someobject(X)”的数组,并在“球”移动

  • 我已经尝试添加冲突检测一段时间了,但似乎做不到... 要绘制地图,我只需使用x,y坐标: 使用这种方法,我想出了这种检测: 我一直在尝试使用for循环遍历树来检测玩家(一个矩形)是否穿过树,但我想不出任何东西。 我已经试过了 如果碰撞=true,player.update(碰撞)将矩形更改为红色,如果为false,将矩形变为黑色。 我已尝试使用for和if,例如: 等但这不起作用,它只适用于wit

  • 所以我试图用Python和Pyplay创建一个益智平台游戏,但是我遇到了一点麻烦。当我为主要角色使用单点图像,而不是矩形图像时,如何制作碰撞检测器?我知道直角图像有左、右、顶部和底部像素功能(这对冲突检测非常有用),但是对于单片图像有这样的功能吗?或者我只需要为x和y坐标创建一个变量图像的宽度/高度?我试过用那个 但是catImg一直在通过窗户的尽头。我做错了什么?提前谢谢。

  • 我有一些关于碰撞角度的问题。我正在尝试为一个游戏编写物理代码,我不想使用任何第三方库,实际上我想自己编写每一个东西。我知道如何检测两个球体之间的碰撞,但我不知道如何找到两个球体之间的碰撞/斥力角。我试过扭转物体的方向,但没有成功。如果你把我链接到一个有趣的.pdf文件教物理编程,那将是非常好的。