簡體   English   中英

如何在Singleton的快速Sprite Kit游戲中顯示分數標簽

[英]How to display a score label in a swift Sprite Kit game with Singleton

我已經嘗試了幾天,以實現單例方法來更新我正在制作的游戲的每個級別的分數。 我不知道實現它的正確方法。 在構建和運行項目時,我沒有任何錯誤,但是在運行游戲時,分數標簽不會顯示。 我不知道為什么,但是我知道這與單例方法未正確實現有關。 任何輸入將不勝感激。 下面的代碼是我的第一個開場場景,目前還沒有顯示得分標簽或得分。

這是游戲的第一級:

import SpriteKit

class Singleton {

static let sharedInstance = Singleton()
var ScoreLabel = UILabel()
var Score : Int = 0


}



struct PhysicsCategory {
static let Enemy : UInt32 = 1
static let Bullet : UInt32 = 2
static let Player : UInt32 = 3
}



class GameScene: SKScene, SKPhysicsContactDelegate {
var HighScore = Int()
var Player = SKSpriteNode(imageNamed: "GoodGuy.png")
var Level1Label = UILabel()


override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    var timer = NSTimer.scheduledTimerWithTimeInterval(5.0, target: self, selector: "update", userInfo: nil, repeats: true)

    var HighScoreDefault = NSUserDefaults.standardUserDefaults()
    if (HighScoreDefault.valueForKey("HighScore") != nil){

        HighScore = HighScoreDefault.valueForKey("HighScore") as! NSInteger
    }
    else{
        HighScore = 0
    }




    physicsWorld.contactDelegate = self

    self.scene?.backgroundColor = UIColor.blackColor()

    self.scene?.size = CGSize(width:640, height: 1136)

    self.addChild(SKEmitterNode(fileNamed: "MagicParticle")!)

    Player.position = CGPointMake(self.size.width/2, self.size.height/8)
    Player.physicsBody = SKPhysicsBody (rectangleOfSize: Player.size)
    Player.physicsBody?.affectedByGravity = false
    Player.physicsBody?.categoryBitMask = PhysicsCategory.Player
    Player.physicsBody?.contactTestBitMask = PhysicsCategory.Enemy
    Player.physicsBody?.dynamic = false

    Level1Label = UILabel (frame: CGRect(x:0, y:0, width: view.frame.size.width/3, height: 30))
    Level1Label.center = CGPoint(x: view.frame.size.width/1.675 , y: view.frame.size.height/1.05)
    Level1Label.textColor = UIColor.whiteColor()
    Level1Label.text = "Level 1"
    self.view?.addSubview(Level1Label)

    Singleton.sharedInstance.ScoreLabel.text = "\(Singleton.sharedInstance.Score)"
    Singleton.sharedInstance.ScoreLabel = UILabel(frame: CGRect(x:0, y:0, width:100, height:20))
    Singleton.sharedInstance.ScoreLabel.backgroundColor = UIColor.clearColor()
    Singleton.sharedInstance.ScoreLabel.textColor = UIColor.whiteColor()
    self.view?.addSubview(Singleton.sharedInstance.ScoreLabel)


    var Timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("SpawnBullets"), userInfo: nil, repeats: true)

    var Enemytimer = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: Selector("SpawnEnemies"), userInfo: nil, repeats: true)



    self.addChild(Player)





}

func update() {
    self.view?.presentScene(GameScene2())
    Level1Label.removeFromSuperview()
}

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody : SKPhysicsBody = contact.bodyA
    var secondBody : SKPhysicsBody = contact.bodyB
    if ((firstBody.categoryBitMask == PhysicsCategory.Enemy) && (secondBody.categoryBitMask == PhysicsCategory.Bullet) ||
        (firstBody.categoryBitMask == PhysicsCategory.Bullet) && (secondBody.categoryBitMask == PhysicsCategory.Enemy)){

        CollisionWithBullet(firstBody.node as! SKSpriteNode, Bullet: secondBody.node as! SKSpriteNode)

    }

    else if ((firstBody.categoryBitMask == PhysicsCategory.Enemy) && (secondBody.categoryBitMask == PhysicsCategory.Player) ||
        (firstBody.categoryBitMask == PhysicsCategory.Player) && (secondBody.categoryBitMask == PhysicsCategory.Enemy)){

            CollisionWithPlayer(firstBody.node as! SKSpriteNode, Player: secondBody.node as! SKSpriteNode)
    }


}


func CollisionWithBullet(Enemy: SKSpriteNode, Bullet: SKSpriteNode){
    Enemy.removeFromParent()
    Bullet.removeFromParent()
    Singleton.sharedInstance.Score++


    Singleton.sharedInstance.ScoreLabel.text = "\(Singleton.sharedInstance.Score)"
}



func CollisionWithPlayer(Enemy: SKSpriteNode, Player: SKSpriteNode){
    var ScoreDefault = NSUserDefaults.standardUserDefaults()
    ScoreDefault.setValue(Singleton.sharedInstance.Score, forKey: "Score")
    ScoreDefault.synchronize()


    if (Singleton.sharedInstance.Score > HighScore){

    var HighScoreDefault = NSUserDefaults.standardUserDefaults()
    HighScoreDefault.setValue(Singleton.sharedInstance.Score, forKey: "HighScore")

    }


    Enemy.removeFromParent()
    Player.removeFromParent()
    self.view?.presentScene(EndScene())
    Level1Label.removeFromSuperview()

        }

func SpawnBullets(){
    var Bullet = SKSpriteNode(imageNamed: "Bullet.png")
    Bullet.zPosition = -5
    Bullet.position = CGPointMake(Player.position.x, Player.position.y)

    let action = SKAction.moveToY(self.size.height + 30, duration: 1.0)
    let actionDone = SKAction.removeFromParent()
    Bullet.runAction(SKAction.sequence([action, actionDone]))


    Bullet.physicsBody = SKPhysicsBody(rectangleOfSize: Bullet.size)
    Bullet.physicsBody?.categoryBitMask = PhysicsCategory.Bullet
    Bullet.physicsBody?.contactTestBitMask = PhysicsCategory.Enemy
    Bullet.physicsBody?.affectedByGravity = false
    Bullet.physicsBody?.dynamic = false
    self.addChild(Bullet)
}

func SpawnEnemies(){
    var Enemy = SKSpriteNode(imageNamed: "BadGuy.png")
    var MinValue = self.size.width/8
    var MaxValue = self.size.width - 150
    let SpawnPoint = UInt32(MaxValue - MinValue)
    Enemy.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.size.height)
    Enemy.physicsBody = SKPhysicsBody(rectangleOfSize: Enemy.size)
    Enemy.physicsBody?.categoryBitMask = PhysicsCategory.Enemy
    Enemy.physicsBody?.contactTestBitMask = PhysicsCategory.Bullet
    Enemy.physicsBody?.affectedByGravity = false
    Enemy.physicsBody?.dynamic = true

    let action = SKAction.moveToY(-70, duration: 3.0)
    let actionDone = SKAction.removeFromParent()
    Enemy.runAction(SKAction.sequence([action, actionDone]))

    Enemy.runAction(SKAction.repeatActionForever(action))

    self.addChild(Enemy)

}



override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
   /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)

        Player.position.x = location.x

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

        Player.position.x = location.x

    }
}
override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}
}

這是游戲的第二層:

導入SpriteKit

struct PhysicsCategory2 {
static let Enemy : UInt32 = 1//00000000000000000000000000000001
static let Bullet : UInt32 = 2//00000000000000000000000000000010
static let Player : UInt32 = 3//00000000000000000000000000000100
}


class GameScene2: SKScene, SKPhysicsContactDelegate {
var HighScore = Int()
var Player = SKSpriteNode(imageNamed: "GoodGuy.png")
var Level2Label = UILabel()


override func didMoveToView(view: SKView) {
    /* Setup your scene here */

    var HighScoreDefault = NSUserDefaults.standardUserDefaults()
    if (HighScoreDefault.valueForKey("HighScore") != nil){

        HighScore = HighScoreDefault.valueForKey("HighScore") as! NSInteger
    }
    else{
        HighScore = 0
    }



    physicsWorld.contactDelegate = self

    self.scene?.backgroundColor = UIColor.blackColor()

    self.scene?.size = CGSize(width:640, height: 1136)

    self.addChild(SKEmitterNode(fileNamed: "MagicParticle")!)

    Player.position = CGPointMake(self.size.width/2, self.size.height/8)
    Player.physicsBody = SKPhysicsBody (rectangleOfSize: Player.size)
    Player.physicsBody?.affectedByGravity = false
    Player.physicsBody?.categoryBitMask = PhysicsCategory2.Player
    Player.physicsBody?.contactTestBitMask = PhysicsCategory2.Enemy
    Player.physicsBody?.dynamic = false

    Level2Label = UILabel (frame: CGRect(x:0, y:0, width: view.frame.size.width/3, height: 30))
    Level2Label.center = CGPoint(x: view.frame.size.width/1.675 , y: view.frame.size.height/1.05)
    Level2Label.textColor = UIColor.whiteColor()
    Level2Label.text = "Level 2"
    self.view?.addSubview(Level2Label)


    var Timer = NSTimer.scheduledTimerWithTimeInterval(1.0, target: self, selector: Selector("SpawnBullets"), userInfo: nil, repeats: true)

    var Enemytimer = NSTimer.scheduledTimerWithTimeInterval(1.5, target: self, selector: Selector("SpawnEnemies"), userInfo: nil, repeats: true)



    self.addChild(Player)

    Singleton.sharedInstance.ScoreLabel.text = "\(Singleton.sharedInstance.Score)"
    Singleton.sharedInstance.ScoreLabel = UILabel(frame: CGRect(x:0, y:0, width:100, height:20))
    Singleton.sharedInstance.ScoreLabel.backgroundColor = UIColor.clearColor()
    Singleton.sharedInstance.ScoreLabel.textColor = UIColor.whiteColor()



}

func didBeginContact(contact: SKPhysicsContact) {
    var firstBody : SKPhysicsBody = contact.bodyA
    var secondBody : SKPhysicsBody = contact.bodyB
    if ((firstBody.categoryBitMask == PhysicsCategory2.Enemy) && (secondBody.categoryBitMask == PhysicsCategory2.Bullet) ||
        (firstBody.categoryBitMask == PhysicsCategory2.Bullet) && (secondBody.categoryBitMask == PhysicsCategory2.Enemy)){

            CollisionWithBullet(firstBody.node as! SKSpriteNode, Bullet: secondBody.node as! SKSpriteNode)

    }

    else if ((firstBody.categoryBitMask == PhysicsCategory2.Enemy) && (secondBody.categoryBitMask == PhysicsCategory2.Player) ||
        (firstBody.categoryBitMask == PhysicsCategory2.Player) && (secondBody.categoryBitMask == PhysicsCategory2.Enemy)){

            CollisionWithPlayer(firstBody.node as! SKSpriteNode, Player: secondBody.node as! SKSpriteNode)
    }


    }


    func CollisionWithBullet(Enemy: SKSpriteNode, Bullet: SKSpriteNode){
    Enemy.removeFromParent()
    Bullet.removeFromParent()
    Singleton.sharedInstance.Score++


    Singleton.sharedInstance.ScoreLabel.text = "\(Singleton.sharedInstance.Score)"
}




func CollisionWithPlayer(Enemy: SKSpriteNode, Player: SKSpriteNode){
    var ScoreDefault = NSUserDefaults.standardUserDefaults()
    ScoreDefault.setValue(Singleton.sharedInstance.Score, forKey: "Score")
    ScoreDefault.synchronize()

    if (Singleton.sharedInstance.Score > HighScore){

        var HighScoreDefault = NSUserDefaults.standardUserDefaults()
        HighScoreDefault.setValue(Singleton.sharedInstance.Score, forKey: "HighScore")

    }


    Enemy.removeFromParent()
    Player.removeFromParent()
    self.view?.presentScene(EndScene())
    Level2Label.removeFromSuperview()
    Singleton.sharedInstance.ScoreLabel.removeFromSuperview()

    }

    func SpawnBullets(){
    var Bullet = SKSpriteNode(imageNamed: "Bullet.png")
    Bullet.zPosition = -5
    Bullet.position = CGPointMake(Player.position.x, Player.position.y)

    let action = SKAction.moveToY(self.size.height + 30, duration: 1.0)
    let actionDone = SKAction.removeFromParent()
    Bullet.runAction(SKAction.sequence([action, actionDone]))


    Bullet.physicsBody = SKPhysicsBody(rectangleOfSize: Bullet.size)
    Bullet.physicsBody?.categoryBitMask = PhysicsCategory2.Bullet
    Bullet.physicsBody?.contactTestBitMask = PhysicsCategory2.Enemy
    Bullet.physicsBody?.affectedByGravity = false
    Bullet.physicsBody?.dynamic = false
    self.addChild(Bullet)
    }

    func SpawnEnemies(){
    var Enemy = SKSpriteNode(imageNamed: "BadGuy.png")
    var MinValue = self.size.width/8
    var MaxValue = self.size.width - 150
    let SpawnPoint = UInt32(MaxValue - MinValue)
    Enemy.position = CGPoint(x: CGFloat(arc4random_uniform(SpawnPoint)), y: self.size.height)
    Enemy.physicsBody = SKPhysicsBody(rectangleOfSize: Enemy.size)
    Enemy.physicsBody?.categoryBitMask = PhysicsCategory2.Enemy
    Enemy.physicsBody?.contactTestBitMask = PhysicsCategory2.Bullet
    Enemy.physicsBody?.affectedByGravity = false
    Enemy.physicsBody?.dynamic = true

    let action = SKAction.moveToY(-70, duration: 3.0)
    let actionDone = SKAction.removeFromParent()
    Enemy.runAction(SKAction.sequence([action, actionDone]))

    Enemy.runAction(SKAction.repeatActionForever(action))

    self.addChild(Enemy)

    }



    override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
    /* Called when a touch begins */

    for touch in touches {
        let location = touch.locationInNode(self)

        Player.position.x = location.x

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

        Player.position.x = location.x

    }
}
override func update(currentTime: CFTimeInterval) {
    /* Called before each frame is rendered */
}
}

這是游戲的“游戲結束”頁面:

import Foundation
import SpriteKit

class EndScene: SKScene {

var RestartButton : UIButton!
var HighScore : Int!
var HighScoreLabel : UILabel!
var GameOverLabel : UILabel!
override func didMoveToView(view: SKView) {

    self.scene?.backgroundColor = UIColor.blackColor()

    self.scene?.size = CGSize(width:640, height: 1136)

    self.addChild(SKEmitterNode(fileNamed: "MagicParticle")!)

    RestartButton = UIButton(frame: CGRect(x:0, y:0, width: view.frame.size.width/3
        , height: 30))
    RestartButton.titleLabel?.adjustsFontSizeToFitWidth = true
    RestartButton.center = CGPoint(x: view.frame.size.width/2 , y: view.frame.size.height/1.5)
    RestartButton.setTitle("Restart", forState: UIControlState.Normal)
    RestartButton.showsTouchWhenHighlighted = true
    RestartButton.setTitleColor(UIColor.whiteColor(), forState:  UIControlState.Normal)
    RestartButton.addTarget(self, action: Selector("Restart"), forControlEvents: UIControlEvents.TouchUpInside)
    self.view?.addSubview(RestartButton)

    var ScoreDefault = NSUserDefaults.standardUserDefaults()
    var Score = ScoreDefault.valueForKey("Score") as! NSInteger

    var HighScoreDefault = NSUserDefaults.standardUserDefaults()
    HighScore = HighScoreDefault.valueForKey("HighScore") as! NSInteger

    Singleton.sharedInstance.ScoreLabel = UILabel (frame: CGRect(x:0, y:0, width: view.frame.size.width/3, height: 30))
    Singleton.sharedInstance.ScoreLabel.center = CGPoint(x: view.frame.size.width/1.6 , y: view.frame.size.height/2.5)
    Singleton.sharedInstance.ScoreLabel.text = "\(Singleton.sharedInstance.Score)"
    Singleton.sharedInstance.ScoreLabel.textColor = UIColor.whiteColor()
    self.view?.addSubview(Singleton.sharedInstance.ScoreLabel)

    HighScoreLabel = UILabel (frame: CGRect(x:0, y:0, width: view.frame.size.width/3, height: 30))
    HighScoreLabel.center = CGPoint(x: view.frame.size.width/1.6 , y: view.frame.size.height/2)
    HighScoreLabel.textColor = UIColor.whiteColor()
    HighScoreLabel.text = "\(HighScore)"
    self.view?.addSubview(HighScoreLabel)

    GameOverLabel = UILabel (frame: CGRect(x:0, y:0, width: view.frame.size.width/3.8, height: 30))
    GameOverLabel.center = CGPoint(x: view.frame.size.width/2 , y: view.frame.size.height/10)
    GameOverLabel.textColor = UIColor.whiteColor()
    GameOverLabel.text = "Game Over"
    self.view?.addSubview(GameOverLabel)

}

func Restart(){
    self.view?.presentScene(GameScene(), transition: SKTransition.crossFadeWithDuration(0.3))
    RestartButton.removeFromSuperview()
    HighScoreLabel.removeFromSuperview()
    Singleton.sharedInstance.ScoreLabel.removeFromSuperview()
    GameOverLabel.removeFromSuperview()

}
}

我想一個新的問題是,是否需要做其他事情以使單例方法在場景之間工作,而不是更改變量的名稱。

您在哪里調用DisplayGameScore()? (你不)

除此之外,這不是很好

static let ScoreLabel = Singleton()
static let Score = Singleton()

您創建了兩個Singleton實例,這是錯誤的

然后你有一個實例名稱相同的實例變量ScoreLabel也不是很好

正如其他人所說,您創建了2個單例。

要正確使用它,您應該只在單例課程中這樣做

static let sharedInstance = Singelton()

而不是在游戲場景中使用分數屬性或其他屬性/方法,您會這樣說

Singleton.sharedInstance.score++ 
Singleton.sharedInstance.scoreLabel ...
Singleton.sharedInstance.displayGameScore()

您也可以在GameScene中這樣寫

 let singleton = Singleton.sharedInstance
 singleton.score++
 singleton.scoreLabel...
 singleton.displayGameScore()

附帶說明一下,最佳做法是編寫這樣的屬性/方法

var score...
func displayGameScore()...

var Score....
func DisplayGameScore() ...

另一方面,如果使用SpriteKit Apis,則可能應該使用SpriteKit Apis,因此應使用SKLabelNodes代替UILabel。 此外,display gameScore方法可能可以進入您的GameScene中,而不僅僅是引用Singleton中的score屬性。

暫無
暫無

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

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