簡體   English   中英

具有兩個物理實體的節點

[英]Node with Two Physics Bodies

我知道這個問題在這里已經被“提出” 了,但它沒有幫助,也沒有涵蓋我的要求。

話雖如此,我想知道如何實現以下目標:

  • 我需要一個node具有2個物理機構:1)一個較小的機構(200×200表示該節點的幀),和2)一個大的主體(500×500),表示將作為一個“檢測”邊界的區域的外周。 外部物體不會物理地碰撞碰撞的物體,它只需要記錄物體已遇到該邊界線。 以下是我所描述的簡單想法:

在此處輸入圖片說明

我最初的方法是使用SKPhysicsBody bodyWithBodies:<NSArray>但那會創建重疊體作為較小的rect。

因此,我想必須為較小的主體(黑色正方形)創建一個SKSpriteNode ,為較大的主體(藍色正方形)創建另一個SKSpriteNode ,並將其作為子對象添加到較小的正方形(反之亦然)。

我的問題是在注冊該交互時,我似乎無法獲得允許其他對象通過的外部邊界。 我最近來的就是讓一個可移動的節點到達邊界,然后只要我嘗試通過邊界,就不斷沿500x500邊界線來回推動。 我已經能夠使移動節點無法通過500x500,但這與我所需要的相反。

這是我正在使用的代碼,也許有人可以看到我做錯的事情:

/// TESTING

// Detection body - 500x500
SKSpriteNode *dbody = [SKSpriteNode spriteNodeWithImageNamed:@"object500"];
dbody.position = CGPointMake(500, 100);
dbody.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:dbody.frame];
dbody.physicsBody.categoryBitMask = detection;
dbody.physicsBody.collisionBitMask = 0;
dbody.physicsBody.contactTestBitMask = player;

// Node body - 200x200
SKSpriteNode *testBoundary = [SKSpriteNode spriteNodeWithImageNamed:@"object"];
testBoundary.physicsBody = [SKPhysicsBody bodyWithEdgeLoopFromRect:testBoundary.frame];
testBoundary.physicsBody.categoryBitMask = object;
testBoundary.physicsBody.contactTestBitMask = player;
testBoundary.position = dbody.position;

// Add boundary as child to main node
[testBoundary addChild:dbody];

// Add to scene
[chapterScene addChild:dbody];

所有這一切都是內部LevelScene.m,一個SKScene設定<SKPhysicsContactDelegate>在頭中。 另外,我已經定義了chapterScene

// Set up main chapter scene
self.anchorPoint = CGPointMake(0.5, 0.5); //0,0 to 1,1
chapterScene = [SKNode node];
[self addChild:chapterScene];

,並在chapterScene的頂部定義了ChapterScene。

@interface LevelScene () {

#pragma 1 Scene objects
    SKNode *chapterScene;

}

如果有人可以幫助我弄清楚我在做錯什么,或者可以選擇一種替代方法來滿足我的需求,我將不勝感激。

注意:就CPU和內存而言,我的備份解決方案看似昂貴,但我相信它仍然可以使用。 我將有一個BOOL isDetected來表示移動的播放器節點是否在500x500區域內,然后在update我將監視到500x500節點中心的較小200x200矩形邊界的距離。 但是我寧願使用2 SKPhysicsBody ,因為我確信它可以完成並且將更容易實現。

更新:這是我的移動角色(一個單獨的SKNode類,稱為Character.m

- (void)createCharacterWithName:(NSString *)charName {

    character = [SKSpriteNode spriteNodeWithImageNamed:charName];
    [self addChild:character];

    self.physicsBody = [SKPhysicsBody bodyWithCircleOfRadius:character.frame.size.width/2.0];
    self.physicsBody.dynamic = YES;
    self.physicsBody.allowsRotation = YES;

    // Define physics body relationships
    self.physicsBody.categoryBitMask = player;
    self.physicsBody.collisionBitMask = player;
    self.physicsBody.contactTestBitMask = detection;

}

這是我的模擬器的圖像(正如我的描述,在大小上有些不同。我的描述是為了便於理解,而不是節點的精確縮放) 在此處輸入圖片說明

這為我工作。 抱歉,我沒有在obj c上寫它。 很快我就快了很多

import SpriteKit

let CategoryOuter:UInt32     = 1 << 0
let CategoryInner:UInt32     = 1 << 1
let CategoryTester:UInt32    = 1 << 2

class GameScene: SKScene, SKPhysicsContactDelegate {

    let outerSprite = SKSpriteNode(color: SKColor.redColor(), size: CGSizeMake(100, 100))
    let innerSprite = SKSpriteNode(color: SKColor.blueColor(), size: CGSizeMake(40, 40))
    let tester = SKSpriteNode(color: SKColor.greenColor(), size: CGSizeMake(10, 10))

    override init(size: CGSize) {
        super.init(size: size)
        physicsWorld.contactDelegate = self
        physicsWorld.gravity = CGVectorMake(0, 0)

        outerSprite.position = CGPointMake(size.width/2, size.height/2)
        outerSprite.physicsBody = SKPhysicsBody(rectangleOfSize: outerSprite.size)
        outerSprite.physicsBody!.dynamic = false
        outerSprite.physicsBody!.categoryBitMask = CategoryOuter
        outerSprite.physicsBody!.collisionBitMask = 0
        outerSprite.physicsBody!.contactTestBitMask = CategoryTester

        innerSprite.physicsBody = SKPhysicsBody(rectangleOfSize: innerSprite.size)
        innerSprite.physicsBody!.dynamic = false
        innerSprite.physicsBody!.categoryBitMask = CategoryInner
        innerSprite.physicsBody!.collisionBitMask = CategoryTester
        innerSprite.physicsBody!.contactTestBitMask = CategoryTester

        outerSprite.addChild(innerSprite)
        addChild(outerSprite)

        tester.physicsBody = SKPhysicsBody(rectangleOfSize: tester.size)
        tester.physicsBody!.categoryBitMask = CategoryTester
        tester.physicsBody!.collisionBitMask = CategoryInner
        addChild(tester)
    }

    func didBeginContact(contact: SKPhysicsContact) {
        let collision:UInt32 = (contact.bodyA.categoryBitMask | contact.bodyB.categoryBitMask)

        if collision == (CategoryOuter | CategoryTester) {
            print("outer collision")
        }
        else if collision == (CategoryInner | CategoryTester) {
            print("inner collision")
        }
    }

    override func touchesMoved(touches: Set<UITouch>, withEvent event: UIEvent?) {
        if let touch = touches.first {
            let location = touch.locationInNode(self)
            tester.position = location
        }
    }

    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
}

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM