gpt4 book ai didi

swift - 如何设置 SceneKit 碰撞检测

转载 作者:IT王子 更新时间:2023-10-29 05:22:28 26 4
gpt4 key购买 nike

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

编辑:您好,非常感谢,对不起,我忘了说我的项目是快速的。没什么大不了的,我大部分时间都可以自己翻译。

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

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

查看the documentation看来我需要以某种方式将场景物理世界委托(delegate)分配给此方法。我不确定该怎么做。

最佳答案

关于 SceneKit 中碰撞检测的主要内容:

  • 它基于位掩码,它们一起构成了一个表。
  • 联系代表是您应对冲突的方式。

让物体发生碰撞

例如,您可以像这样用简单的英语陈述一些游戏设计:

Asteroids hit each other (and make smaller asteroids). Missiles should pass through each other, but destroy rockets and asteroids. Rockets shouldn't do anything to missiles (only the other way around), but if one gets too close to another or to an asteroid you are having a bad problem and you will not go to space today.

通过碰撞检测实现这一点的第一步是根据哪些对进行交互来编纂该设计。您可以使用表格执行此操作:

         | 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 为您解决碰撞(即,使对象相互弹开)所需的全部内容。

响应碰撞

如果你还想收到碰撞通知(这样你就可以让导弹炸毁东西,然后让你的船撞上小行星结束游戏),你需要设置一个 contact delegate在场景的物理世界中实现一个或多个 contact delegate methods发生联系时会被调用。

在您的联系人委托(delegate)方法(例如 physicsWorld:didBeginContact: )中,您需要找出联系人中涉及的 body 类别,以及哪些 body 类别,这样您就可以获取执行您的游戏的代码为碰撞做的:

- (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 ...
}
}

将此代码放入您的一个类中(一个 View Controller ,也许 - 无论您将游戏逻辑放在何处都是好的),并使该类声明符合 SCNPhysicsContactDelegate协议(protocol)。

@interface ViewController: UIViewController <SCNPhysicsContactDelegate>

然后将该对象作为联系人委托(delegate)分配给场景的物理世界:

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

了解更多

SCNPhysicsBody 中有一些关于冲突解决的内容。引用文档。 Apple 有一些使用碰撞检测的示例代码 — 它是 WWDC 演示大杂烩的一部分 slidesdemo示例应用程序,并在 vehicle physics也有演示。

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

关于swift - 如何设置 SceneKit 碰撞检测,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27372138/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com