Scenario: Since I need to know hitpoints and score of my game objects, I want extend SKPhysicsBody with some more stats. I have asked some related questions alread here and here.
Problem: I get this error "Must call a designated initializer of the superclass 'SKPhysicsBody'". And I do not know what I am doing wrong. I did almost same with SKSpriteNode and super.init
worked. But there I had the problem that collision detection only returns physicsBody
and not SKSpriteNode.
import Foundation
import SpriteKit
class Bubble: SKPhysicsBody {
let bubbleSize = ["large": CGFloat(1.0), "medium": CGFloat(0.5), "small": CGFloat(0.25)]
let playerCategory: UInt32 = 1 << 0
let worldCategory: UInt32 = 1 << 1
let bubbleCategory: UInt32 = 1 << 2
let bulletCategory: UInt32 = 1 << 3
var hitpoints: Int?
var score: Int?
init(bubble: (id: Int, name: String, scale: String, image: String, hitpoints: Int, score: Int)) {
super.init(circleOfRadius: 50)
self.hitpoints = bubble.hitpoints
self.score = bubble.score
self.dynamic = true
self.friction = 0.5
self.restitution = 1
self.linearDamping = 0
self.angularDamping = 0
self.mass = 0.3
self.categoryBitMask = bubbleCategory
self.collisionBitMask = worldCategory
self.contactTestBitMask = worldCategory | playerCategory
}
required init(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
Edit: When I use super.init()
I do not get any errors. But how can I set its size like circleOfRadius
or rectangleOfSize
? Normally it should work with super.init(circleOfRadius: <CGFloat>)
!
The initializer you are attempting to call is derived from conversion of the Objective C factory method:
+ (SKPhysicsBody *)bodyWithCircleOfRadius:(CGFloat)r;
By command clicking on the class in your code, you can see that it is presented to Swift as:
/*not inherited*/ init(circleOfRadius r: CGFloat)
For contrast, the UIView initializer:
- (instancetype)initWithFrame:(CGRect)frame NS_DESIGNATED_INITIALIZER;
is seen in Swift as:
init(frame: CGRect)
without the /*not inherited*/
comment.
The reason for the difference is that the factory method underlying the SKPhysicsBody initializer always returns a concrete instance of SKPhysicsBody, while initWithFrame is an instance method returning instancetype
, allowing it to be used in subclass initialization.
Your subclass therefore cannot rely on any of the standard initializers for SKPhysicsBody.