收集硬币并添加到精灵套装中的分数标签中



我正试图在我的游戏中使用本教程作为参考来实现一个简单的评分系统:

http://www.raywenderlich.com/87232/make-game-like-mega-jump-sprite-kit-swift-part-2

问题是,如果我尝试按原样实现,它会在GameScene.swift中崩溃

 let another = whichNode as! GameObjectNode

以下是玩家收集硬币的代码的主要部分。如果你想更仔细、更好地看一看,我也可以邀请你参加我的回购。我知道看我贴在这里的代码会很难。

GameObjectNode.swift:

enum CoinType: Int {
  case Normal = 0
  case Special
}
struct CollisionCategoryBitmask {
  static let Player: UInt32 = 0x00
  static let Coin: UInt32 = 0x01
  static let Platform: UInt32 = 0x02
}
class GameObjectNode: SKNode {
func collisionWithPlayer(player: SKNode) -> Bool {
    return false
}
func checkNodeRemoval(playerY: CGFloat) {
    if playerY > self.position.y + 300.0 {
        self.removeFromParent()
    }
  }
}
class CoinNode: GameObjectNode {
let coinSound = SKAction.playSoundFileNamed("StarPing.wav", waitForCompletion: false)
var coinType: CoinType!
override func collisionWithPlayer(player: SKNode) -> Bool {
    // Boost the player up
    player.physicsBody?.velocity = CGVector(dx: player.physicsBody!.velocity.dx, dy: 400.0)
    // Play sound
    runAction(coinSound, completion: {
        // Remove this Star
        self.removeFromParent()
    })
    // Award score
    GameState.sharedInstance.score += (coinType == .Normal ? 20 : 100)
    // Award stars
    GameState.sharedInstance.coins += (coinType == .Normal ? 1 : 5)
    // The HUD needs updating to show the new stars and score
    return true
  }
}

GameState.swift

class GameState {
  var score: Int
  var highScore: Int
  var coins: Int
  init() {
    // Init
    score = 0
    highScore = 0
    coins = 0
    // Load game state
    let defaults = NSUserDefaults.standardUserDefaults()
    highScore = defaults.integerForKey("highScore")
    coins = defaults.integerForKey("coins")
  }
  func saveState() {
    // Update highScore if the current score is greater
    highScore = max(score, highScore)
    // Store in user defaults
    let defaults = NSUserDefaults.standardUserDefaults()
    defaults.setInteger(highScore, forKey: "highScore")
    defaults.setInteger(coins, forKey: "coins")
    NSUserDefaults.standardUserDefaults().synchronize()
  }
  class var sharedInstance: GameState {
    struct Singleton {
        static let instance = GameState()
    }
    return Singleton.instance
  }
}

和GameScene.swift:

import SpriteKit
import CoreMotion
import GameplayKit
struct PhysicsCategory {
 static let None: UInt32              = 0
 static let Player: UInt32            = 0b1      // 1
 static let PlatformNormal: UInt32    = 0b10     // 2
 static let PlatformBreakable: UInt32 = 0b100    // 4
 static let CoinNormal: UInt32        = 0b1000   // 8
 static let CoinSpecial: UInt32       = 0b10000  // 16
 static let Edges: UInt32             = 0b100000 // 32
}
class GameScene: SKScene, SKPhysicsContactDelegate {
 // Other Properties
  ...
 var player: SKSpriteNode!
 // HUD 
 var hudNode: SKNode!
 var lblScore: SKLabelNode!
 var lblCoins: SKLabelNode!
 override func didMoveToView(view: SKView) {
 ....
  // HUD
   hudNode = SKNode()
   hudNode.zPosition = 1000
   cameraNode.addChild(hudNode)
  // Coins
   let coin = SKSpriteNode(imageNamed: "powerup05_1")
   coin.position = convertPoint(CGPoint(x: 300, y: self.size.height-100), toNode: cameraNode)
   coin.zPosition = 1000
   hudNode.addChild(coin)
   lblCoins = SKLabelNode(fontNamed: "ChalkboardSE-Bold")
   lblCoins.fontSize = 70
   lblCoins.fontColor = SKColor.whiteColor()
   lblCoins.position = convertPoint(CGPoint(x: 375, y: self.size.height-100), toNode: cameraNode)
   lblCoins.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Left
   lblCoins.zPosition = 1000
   lblCoins.text = String(format: "X %d", GameState.sharedInstance.coins)
   hudNode.addChild(lblCoins)
   // Score
   // 4
   lblScore = SKLabelNode(fontNamed: "ChalkboardSE-Bold")
   lblScore.fontSize = 70
   lblScore.fontColor = SKColor.whiteColor()
   lblScore.position = convertPoint(CGPoint(x: self.size.width-325, y: self.size.height-100), toNode: cameraNode)
   lblScore.horizontalAlignmentMode = SKLabelHorizontalAlignmentMode.Right
   lblScore.zPosition = 1000
   lblScore.text = "0"
   hudNode.addChild(lblScore)
}
 func setupNodes() {
  ...
    player = fgNode.childNodeWithName("Player") as! SKSpriteNode
 }
   func createStarAtPosition(position: CGPoint, ofType type: CoinType) -> CoinNode {
    // 1
    let node = CoinNode()
    let thePosition = CGPoint(x: position.x * scaleFactor, y: position.y)
    node.position = thePosition
    node.name = "NODE_COIN"
    // 2
    node.coinType = type
    var sprite: SKSpriteNode
    if type == .Special {
        sprite = SKSpriteNode(imageNamed: "CoinSpecial")
    } else {
        sprite = SKSpriteNode(imageNamed: "Coin")
    }
    node.addChild(sprite)
    // 3
    node.physicsBody = SKPhysicsBody(circleOfRadius: sprite.size.width / 2)
    // 4
    node.physicsBody?.dynamic = false
    node.physicsBody?.categoryBitMask = CollisionCategoryBitmask.Coin
    node.physicsBody?.collisionBitMask = 0
    node.physicsBody?.contactTestBitMask = 0
    return node
   }
 func didBeginContact(contact: SKPhysicsContact) {
    let other = contact.bodyA.categoryBitMask == PhysicsCategory.Player ? contact.bodyB : contact.bodyA
    var updateHUD = false
    let whichNode = (contact.bodyA.node != player) ? contact.bodyA.node : contact.bodyB.node
    // Code crashes here
    let another = whichNode as! GameObjectNode
    updateHUD = another.collisionWithPlayer(player)
    if updateHUD {
        lblCoins.text = String(format: "X %d", GameState.sharedInstance.coins)
        lblScore.text = String(format: "%d", GameState.sharedInstance.score)
    }
   switch other.categoryBitMask {
     case PhysicsCategory.CoinNormal:
       if let coin = other.node as? SKSpriteNode {
         emitParticles("CollectNormal", sprite: coin)
         jumpPlayer()
         runAction(soundCoin)
    }
     case PhysicsCategory.CoinSpecial:
       if let coin = other.node as? SKSpriteNode {
         emitParticles("CollectSpecial", sprite: coin)
         boostPlayer()
         runAction(soundBoost)
     }
    case PhysicsCategory.PlatformNormal:
       if let platform = other.node as? SKSpriteNode {
         if player.physicsBody!.velocity.dy < 0 {
           platformAction(platform, breakable: false)
           jumpPlayer()
           runAction(soundJump)
        }
     }
    case PhysicsCategory.PlatformBreakable:
       if let platform = other.node as? SKSpriteNode {
          if player.physicsBody!.velocity.dy < 0 {
             platformAction(platform, breakable: true)
             jumpPlayer()
             runAction(soundBrick)
      }
    }
       default:
       break;
   }
  }

我不理解你在didBeganContact中使用的代码,但你可以用这种方式定义联系人主体:

 enum Ctg:UInt32
{
  case Coin = 1
  case Hero = 2
  case Villain = 4
  case Car = 8
}
var hero = SKSpriteNode()
hero.physicsBody = SKPhysicsBody(rectangleOfSize: hero.size)
hero.physicsBody?.categoryBitMask = Ctg.Hero.rawValue
hero.physicsBody?.contactTestBitMask = Ctg.Coin.rawValue  | Ctg.Villian.rawValue

var coin = SKSpriteNode()
coin.physicsBody = SKPhysicsBody(rectangleOfSize: coin.size)
coin.physicsBody?.categoryBitMask = Ctg.Coin.rawValue
coin.physicsBody?.contactTestBitMask = Ctg.Hero.rawValue 

func didBeginContact(contact: SKPhysicsContact)
{
    var first = SKNode()
    var sec = SKNode()

   // this way you ensure that the first body is the most valuable Ctg (enum)
    if contact.bodyA.node?.physicsBody?.categoryBitMask > contact.bodyB.node?.physicsBody?.categoryBitMask
    {
        first = contact.bodyA.node!
        sec = contact.bodyB.node!
    }
    else
    {
         first = contact.bodyB.node!
          sec = contact.bodyA.node!
    }

    // this part be sure that the category of first it is of most value that sec
    if first.physicsBody!.categoryBitMask == Ctg.Hero.rawValue &&  sec.physicsBody!.categoryBitMask == Ctg.Coin.rawValue
    {
        hero.coins++
        scene.labelCoins.text = String(coins)

    }
    if first.physicsBody!.categoryBitMask == Ctg.Villain.rawValue &&  sec.physicsBody!.categoryBitMask == Ctg.Hero.rawValue
    {
        gameOver = true
        hero.removeFromParent()
        lostGame()

    }
}

相关内容

  • 没有找到相关文章

最新更新