swift - SKScene - 如何从 SKSpriteNode 获取类
问题描述
我正在使用 spritekit 创建一个场景。我有 3 个类:GameScene、Bullet 和 Enemy。在我的 GameScene 中,我通过 Bullet 和 Enemy 类添加了创建 SKSpriteNode。
var newBullet = Bullet();
newBullet.CreateBullet()
self.addChild(newBullet.GetSpriteNode())
稍后我通过扩展 SKPhysicsContactDelegate 使用碰撞检测。
func didBegin(_ contact: SKPhysicsContact) {
print("collision detected!")
let firstBody = contact.bodyA.node as! SKSpriteNode;
let secondBody = contact.bodyB.node as! SKSpriteNode;
//here's where I'd like to call bullet.hit()
//var bullet = firstBody.GetClass(Bullet)
//bullet.hit()
// I tried - let tempBullet = ((firstBody as? Bullet));
//but firstBody as? Bullet returns nil
//print(firstBody) - it indeed is my bullet sprite... why is it nil?
}
我在上面写了我的伪代码......我将如何获得与 SKSpriteNode 关联的类......?有没有办法让我的类脚本成为 SKSpriteNode 的一部分,如果是这样 - 我如何获取附加的脚本来调用它的函数?
这也是我的子弹课
class Bullet : SKSpriteNode{
var skNode : SKSpriteNode?
func CreateBullet(){
skNode = SKSpriteNode(color: SKColor.white, size: CGSize(width: 2, height: 10))
skNode?.name = "bullet"
skNode?.position = CGPoint(x: 0, y: 0)
skNode?.physicsBody = SKPhysicsBody(rectangleOf: skNode!.size)
skNode?.physicsBody?.isDynamic = true;
skNode?.physicsBody?.allowsRotation = false;
skNode?.physicsBody?.pinned = false;
skNode?.physicsBody?.affectedByGravity = false;
skNode?.physicsBody?.categoryBitMask = PhysicsCategory.Bullet;
skNode?.physicsBody?.collisionBitMask = PhysicsCategory.Enemy;
skNode?.physicsBody?.contactTestBitMask = PhysicsCategory.Enemy;
}
func GetSKNode() -> SKNode{
return skNode!;
}
}
解决方案
不知道为什么要以这种方式创建子弹。我认为它应该看起来更像。当子类化 SKSpriteNode 时,您应该重写初始化程序以添加您自己的自定义设置。
class Bullet: SKSpriteNode {
init() {
let size = CGSize(width: 2, height: 10)
super.init(texture: nil, color: .white, size: size)
self.name = "bullet"
self._setupBody(size: size)
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
//Prefix private methods with an underscore
private func _setupBody(size: CGSize) {
self.physicsBody = SKPhysicsBody(rectangleOf: size)
self.physicsBody?.isDynamic = true
self.physicsBody?.allowsRotation = false
self.physicsBody?.pinned = false
self.physicsBody?.affectedByGravity = false
self.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
self.physicsBody?.collisionBitMask = PhysicsCategory.Enemy
self.physicsBody?.contactTestBitMask = PhysicsCategory.Enemy
}
}
当您尝试将其转换为 Bullet 时它为 nil 的原因是您在调用时创建了 SKSpriteNodenewBullet.CreateBullet()
而不是 Bullet 类的实例。
最后,在物理接触中,接触中有两个物体。我们不知道哪个是敌人,哪个是子弹。所以我们可以为这两种情况编写代码,尽管如果您要检查更多的碰撞,有更好的方法,比如这个答案:Determining Contact Bodies
class BulletScene:SKScene, SKPhysicsContactDelegate {
func didBegin(_ contact: SKPhysicsContact) {
//Case #1: Bullet = bodyA and Enemy = bodyB
if let bullet = contact.bodyA.node as? Bullet, let enemy = contact.bodyB as? Enemy {
print("Bullet was BodyA!")
//Case #2: Bullet = bodyB and Enemy = bodyA
}else if let enemy = contact.bodyA as? Enemy, let bullet = contact.bodyB.node as? Bullet {
print("Bullet was BodyB!")
}
}
}
推荐阅读
- spring-boot - 如何在 Apache Camel 3.XX 路由上设置标头?
- unix - unix将文件更新为可执行的jar文件不起作用
- python - 为什么python不能由多人或长期构建和维护?
- javascript - 无法将 ejs 文件的 url 重定向到在 js 文件中定义的具有两个参数的路由器
- php - Twilio PHP conversation->message->read ,无法使用提供的语法进行排序
- sap-pi - SAP PO 能否构建集成流以并行调用其他 API 并控制依赖项/有效负载?
- javascript - 在调用 (NodeJS) 的 require() 函数后,导出成员的值会发生什么变化?
- javascript - 有没有办法从 JavaScript 导入 .html 文件?
- powershell - PowerShell - 无法验证参数“身份”的参数。参数为空
- python - 将多级列转换为数据框中的特征 [Pandas]