问题
I am building a game with Xcode's spritekit. Its a platform game and right now it functions well with flat ground pieces. I was wondering if it was possible to ignore transparency in the png for collisions. That is to say, If i have a ground piece with a curved floor and transparency filling the troughs, can i make the player walk the curves instead of a square bounding box covering the whole thing? The only example i can find is in the Gamemaker GML language, you can do "precise" collisions such that blank space in the images do not count as part of the sprite. I can supply code if necessary but this seems like more of a conceptual question. Thanks in advance
回答1:
Hey there's a easy solution for this provided in the Apple Documentation.
SKSpriteNode *sprite = [SKSpriteNode spriteNodeWithImageNamed:@"Spaceship"];
sprite.physicsBody = [SKPhysicsBody bodyWithTexture:sprite.texture size:sprite.texture.size];
This creates a physics body around the physical paths of the texture.
Simulating Physics - SpriteKit Programming Guide
回答2:
It's all in how you instantiate the physicsBody of the node in question.
node.physicsBody = [SKPhysicsBody bodyWithRectangleOfSize:node.size];
is probably the easiest and most common way of making a physicsBody, but will also create the issue you've identified above, because, for all collision purposes, the node is a rectangle.
take a look at the documentation for SKPhysicsBody to see the other options available to you. PolygonFromPath and BodyWithBodies are probably the best suited for what you're doing.
回答3:
SKPhysicsBody is the right move, just wanted to note that it does make sense to have a separate (simplified) mask-image for SKPhysicsBody to improve your performance, simplified from color and geometry standpoint, and here's the code:
let birdMask: UInt32 = 0x1 << 0
let pipeMask: UInt32 = 0x1 << 1
//...
pipeImage = SKSpriteNode(imageNamed: "realImage")
//... size and position
let maskTexture = SKSpriteNode(imageNamed: mask)
maskTexture.size = pipeImage!.size // size of texture w/ real imageNamed
pipeImage!.physicsBody?.usesPreciseCollisionDetection = true
pipeImage!.physicsBody = SKPhysicsBody(texture: maskTexture.texture!, size: size)
pipeImage!.physicsBody?.affectedByGravity = false // disable falling down...
pipeImage!.physicsBody?.allowsRotation = false
pipeImage!.physicsBody?.isDynamic = true
pipeImage!.physicsBody?.friction = 0
pipeImage!.physicsBody?.categoryBitMask = pipeMask
pipeImage!.physicsBody?.collisionBitMask = birdMask | pipeMask
pipeImage!.physicsBody?.contactTestBitMask = birdMask | pipeMask
and more detailed example/guide.
来源:https://stackoverflow.com/questions/22770784/sprite-kit-collisions-ignore-transparency