2016-01-19 44 views
0

我正在製作自定義SKSpriteNode,當我逐步調用createShip時,類中的heroShip常量是正確的,但是當我跳回到gameScene時,heroShip常量沒有屬性我在調用createShip時分配,我不知道我做錯了什麼。我曾嘗試使用類函數,但不能使用高度和寬度屬性。從GameScene設置自定義SKSpriteNode的位置

定製SKSpriteNode類

class hero: SKSpriteNode { 
    var width: CGFloat = 0.0 
    var height: CGFloat = 0.0 

    func createShip() -> SKSpriteNode { 
     let heroShip = SKSpriteNode(imageNamed: "heroShip") 
      heroShip.anchorPoint = CGPointMake(1.0, 0.5) 
      heroShip.physicsBody = SKPhysicsBody(rectangleOfSize: heroShip.size) 
      heroShip.physicsBody?.usesPreciseCollisionDetection = true 
       heroShip.zPosition = 1.0 
      heroShip.physicsBody?.mass = 0.02 
      heroShip.physicsBody?.dynamic = true 
      heroShip.physicsBody?.affectedByGravity = false 
      heroShip.physicsBody?.categoryBitMask = ObjectCategory.collisionHeroCategory.rawValue 
      heroShip.physicsBody?.contactTestBitMask = ObjectCategory.sceneCategory.rawValue 
      heroShip.physicsBody?.collisionBitMask = 0x0 | ObjectCategory.sceneCategory.rawValue 

      //heroShip.position = CGPointMake((scene?.frame.size.width)!/6.0, (scene?.frame.size.height)!/2.0) 

     heroShip.position = CGPointMake(width, height) 

     return heroShip 


    } 
} 

我GameScene

class GameScene: SKScene,SKPhysicsContactDelegate{ 


    let background = SKSpriteNode(imageNamed: "background") 
    var score:Int = 0 
    let scoreLabel = SKLabelNode(fontNamed: "Courier") 
    let MotionManager = CMMotionManager() 
    var heroShip = hero() 
    override func didMoveToView(view: SKView) { 
     heroShip.width = self.size.width/6.0 
     heroShip.height = self.size.height/2.0 
     heroShip.createShip() 
     let enemyShip = SKSpriteNode(imageNamed: "enemyShip") 
     /* Setup your scene here */ 
     self.physicsWorld.contactDelegate = self 
     self.physicsBody = SKPhysicsBody(edgeLoopFromRect: CGRectMake(0,heroShip.size.width/1.25,frame.width,frame.height - heroShip.size.width*1.6)) 
     scene?.physicsBody?.contactTestBitMask = ObjectCategory.sceneCategory.rawValue 
     scene?.physicsBody?.categoryBitMask = ObjectCategory.sceneCategory.rawValue 
     background.position = CGPointMake(CGRectGetMidX(self.frame),CGRectGetMidY(self.frame)) 
     scoreLabel.fontColor = SKColor.whiteColor() 
     scoreLabel.text = String(format: "Score: %01u",score) 
     scoreLabel.position = CGPointMake(frame.size.width/2, frame.size.height - scoreLabel.frame.size.width/1.2) 
     scoreLabel.zPosition = 1.0 


     enemyShip.position = CGPointMake(CGRectGetMidX(self.frame), CGRectGetMidY(self.frame)) 
     enemyShip.zPosition = 1.0 
     enemyShip.physicsBody = SKPhysicsBody(rectangleOfSize: heroShip.size) 
     enemyShip.physicsBody?.usesPreciseCollisionDetection = true 
     enemyShip.physicsBody?.mass = 0.02 
     enemyShip.physicsBody?.dynamic = true 
     enemyShip.physicsBody?.affectedByGravity = false 
     enemyShip.physicsBody?.categoryBitMask = ObjectCategory.collisionEnemyCategory.rawValue 
     enemyShip.physicsBody?.contactTestBitMask = ObjectCategory.collisionBulletCategory.rawValue 
     enemyShip.physicsBody?.collisionBitMask = 0x0 

     self.addChild(enemyShip) 
     self.addChild(background) 
     self.addChild(self.heroShip) 
     self.addChild(scoreLabel) 

     if MotionManager.accelerometerAvailable{ 
      MotionManager.startAccelerometerUpdates() 
     } 

    } 

    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) { 
     let bullet = SKSpriteNode(imageNamed: "bullet") 
     bullet.position = CGPointMake(heroShip.position.x, heroShip.position.y) 
     bullet.zPosition = 1.0 
     // Add physics body for collision detection 
     bullet.physicsBody = SKPhysicsBody(rectangleOfSize: bullet.frame.size) 
     bullet.physicsBody?.dynamic = true 
     bullet.physicsBody?.affectedByGravity = false 
     bullet.physicsBody?.categoryBitMask = ObjectCategory.collisionBulletCategory.rawValue 
     bullet.physicsBody?.contactTestBitMask = ObjectCategory.collisionHeroCategory.rawValue 
     bullet.physicsBody?.collisionBitMask = 0x0; 
     let action = SKAction.moveToX(CGRectGetMaxX(self.frame) + bullet.size.width, duration: 0.75) 
     self.addChild(bullet) 
     bullet.runAction(action, completion: { 
      bullet.removeAllActions() 
      bullet.removeFromParent() 
     }) 
    } 

    func didBeginContact(contact: SKPhysicsContact) { 
     if contact.bodyB.categoryBitMask == ObjectCategory.collisionBulletCategory.rawValue && contact.bodyA.categoryBitMask == ObjectCategory.collisionEnemyCategory.rawValue{ 
     score++ 
     } 
    } 



    override func update(currentTime: CFTimeInterval) { 
     let data = MotionManager.accelerometerData 
     if data?.acceleration.x == nil{ 
      print("nil") 
     } 
     else if fabs((data?.acceleration.x)!) > 0.2 { 
      heroShip.physicsBody?.applyForce(CGVectorMake(0.0, CGFloat(40 * (data?.acceleration.x)!))) 
     } 

     scoreLabel.text = String(format: "Score: %01u",score) 


    } 
} 

回答

2

您運行

heroShip.createShip() 

從來就不是做返回的SKSpriteNode什麼。從我所知道的,英雄類是英雄船。對於這個答案的其餘部分,我將假設這個假設。

GameScene的頂部開始,你應該做一些重構。

var heroShip = hero()將被替換使用SKSpriteNode結構初始化:

var heroShip = hero(imageNamed: "heroShip") 

移動到hero類,func createShip() -> SKSpriteNode {應該變成func createShip() {。由於您現在已經使用圖像紋理設置了節點,並且正在使用類作爲節點,所以不需要返回SKSpriteNode

刪除let heroShip = SKSpriteNode(imageNamed: "heroShip")hero將是我們heroShip

heroShip.whatever變量的任何用法替換爲self.whatever。最後,刪除return heroShip

+0

爲什麼使它成爲2步處理?只需重寫便利初始化來處理'SKPhysicsBody',那麼當我創建一個新英雄時不必擔心這個問題 – Knight0fDragon

+0

@ Knight0fDragon我不確定OP的計劃是什麼,所以我沒有碰它。 – Gliderman

+0

好的,對我來說足夠好的回答 – Knight0fDragon

1

你似乎無法理解的是與你的代碼發生。

截至目前createShip()正在創造一艘英雄船,但你從未使用它。

通過查看您的代碼,它似乎不需要createShip()。從看它,英雄是英雄,所以你的init中的代碼。

convenience init(imageNamed: String,sceneSize:CGSize) { 
    let heroTexture = SKTexture(imageNamed: imageNamed) 

    self.init(texture: heroTexture, color: UIColor.whiteColor(), size: heroTexture.size()) //This may need to be tweeked, my mac is dead right now to verify. 
    self.anchorPoint = CGPointMake(1.0, 0.5) 
    self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size) 
    self.physicsBody?.usesPreciseCollisionDetection = true 
    self.zPosition = 1.0 
    self.physicsBody?.mass = 0.02 
    self.physicsBody?.dynamic = true 
    self.physicsBody?.affectedByGravity = false 
    heroShip.physicsBody?.categoryBitMask = ObjectCategory.collisionHeroCategory.rawValue 
     heroShip.physicsBody?.contactTestBitMask = ObjectCategory.sceneCategory.rawValue 
     heroShip.physicsBody?.collisionBitMask = 0x0 | ObjectCategory.sceneCategory.rawValue 

    //self.position = CGPointMake((scene?.frame.size.width)!/6.0, (scene?.frame.size.height)!/2.0) 

    self.position = CGPointMake(sceneSize.width, sceneSize.height) 



} 

您現在遇到另一個問題,那就是你的SKPhysicsBody不會對準你的錨點。

爲了解決這個問題,創建SKPhysicsBody這樣的:

let centerPoint = CGPointMake(self.size.width/2 - (self.size.width * self.anchorPoint.x), self.size.height/2 - (self.size.height * self.anchorPoint.y)) 
self.physicsBody = SKPhysicsBody(rectangleOfSize: self.size, center: centerPoint) 
+0

我解決了這個問題,還需要添加顏色,因爲這是帶有委託構造函數的顏色,再加上我添加了sceneSize,因爲我們在聊天中提到需要它,所以要創建一個英雄,請讓heroShip = hero imageNamed: 「heroShip」,sceneSize:自我。大小) – Knight0fDragon

+0

你還有其他問題,你的其他問題是bodyA永遠不能保證是子彈,所以你需要考慮bodyA是子彈而bodyB是子彈的情況,你的類別需要是2的冪,這些是位掩碼標誌,所以3實際上意味着sceneCategory和collissionHero,因爲在二進制中,3是0011(因此2個類別),但是你需要使它在0100中以二進制形式給它一個唯一的類別 – Knight0fDragon