How to detect contact on different areas of a physicsbody

南楼画角 提交于 2019-12-02 01:14:50

I use this setup in a lot of places. It scales pretty well if you find yourself wanting to add more parts, or weapons, and it lets you visually hide any of those parts or weapons easily. The use of userData can come in handy if you have a lot going on and different enemies have different "things", or you're doing crazy stuff like parenting child sprites to different entities based on gameplay, etc.

-(SKSpriteNode*)makeAnEnemy
{

    SKSpriteNode *mainEnemy;
    SKSpriteNode *enemyHead;
    //setup mainEnemy physics body
    //setup enemyHead physics body
    [mainEnemy addChild:enemyHead];

    // depending on your plans, on hit you could use the following code later:
    SKSpriteNode *theEnemyThatWasHit = (SKSpriteNode*)enemyHead.parent;

    //or you can use userdata and set it all up here
    [mainEnemy.userData setObject:enemyHead forKey:@"myHead"];
    [enemyHead.userData setObject:mainEnemy forKey:@"myBody"];

    return mainEnemy;
}

Using the pinned attribute of a physicsBody makes it easy to create complex sprites with multiple contact zones. Pinning a Physics Body to the Node's Parent:

The default value is NO. If YES, then the node’s position is fixed relative to its parent. The node’s position cannot be changed by actions or physics forces. The node can freely rotate around its position in response to collisions or other forces. If the parent node has a physics body, then the two physics bodies are treated as if they are connected with a pin joint.

Here is a basic Dog class, where the dog has a main body and a head. Note that I set allowsRotation = false as well so the head cannot move around the body.

import SpriteKit

// for readability
let mainSize = CGSize(width: 300, height: 300)
let headSize = CGSize(width: 100, height: 100)

class Dog : SKSpriteNode {

    let head = SKSpriteNode(color: SKColor.greenColor(), size: headSize)

    init() {
        super.init(texture: nil, color: SKColor.redColor(), size: mainSize)

        head.position = CGPoint(x: mainSize.width - headSize.width, y: 0)
        addChild(head)
    }

    // called after Dog has been added to the scene
    func configurePhysicsBody() {

        physicsBody = SKPhysicsBody(circleOfRadius: mainSize.width / 2)
        physicsBody.dynamic = true
        physicsBody.allowsRotation = false
        // set contactBitmask for main body

        head.physicsBody = SKPhysicsBody(circleOfRadius: headSize.width / 2)
        head.physicsBody.dynamic = true
        head.physicsBody.allowsRotation = false
        // The head is pinned to the parent node, so position is fixed relative to parent
        head.physicsBody.pinned = true
        // set contactBitmask for head

    }

}

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!