Swift 3 更新带有递增整数的标签节点

标签 swift sprite-kit

我是编码新手,请多关照。我正在用 Swift 3 创建一个类似于 Flappy Bird 的游戏,但我的得分节点有问题。我已经为分数创建了一个标签节点,但是当玩家接触 scoreDetect 节点时,没有添加任何分数。我不知道是我对添加点的部分进行了编码还是我的物理代码不正确。任何帮助表示赞赏。谢谢。

import SpriteKit
import GameplayKit

struct PhysicsCategory {

static let player : UInt32 = 0x1 << 1
static let roof : UInt32 = 0x1 << 2
static let floor : UInt32 = 0x1 << 3
static let lowerObstacle : UInt32 = 0x1 << 4
static let upperObstacle : UInt32 = 0x1 << 5
static let scoreDetect : UInt32 = 0x1 << 6

}

class GameScene: SKScene, SKPhysicsContactDelegate {

var bgColor = UIColor(red: 39/255, green: 41/255, blue: 56/255, alpha: 1.0)
var roof = SKSpriteNode()
var floor = SKSpriteNode()
var lowerObstacle = SKSpriteNode()
var upperObstacle = SKSpriteNode()
var player = SKSpriteNode()
var randomValue = Int()
var scoreDetect = SKSpriteNode()
var scoreLabel = SKLabelNode()
var scoreValue = Int()
var logo = SKSpriteNode()
var gameStarted = Bool()

override func didMove(to view: SKView) {

        createPlayer()
        createTiles()
        createScoreLabel()

        physicsWorld.contactDelegate = self
        self.physicsWorld.gravity = CGVector(dx: 0.0, dy: -4.0)
        backgroundColor = bgColor

        let delay = SKAction.wait(forDuration: 3)
        let repeatingAction = SKAction.run(repeatingSequence)
        let sequence = SKAction.sequence([ delay, repeatingAction ])
        run(SKAction.repeatForever(sequence))

}

// Random Selector For Obstacles

func randomSelector() -> Int {

    let array = [1, 2, 3]
    return  Int(arc4random_uniform(UInt32(array.count)))

}

// Player Rules

func createPlayer() {

    player = SKSpriteNode(imageNamed: "Player")
    player.setScale(0.4)
    player.position = CGPoint(x: -player.size.width, y: 0)
    player.zPosition = 2
    addChild(player)

    player.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Player"), size: player.size)
    player.physicsBody?.categoryBitMask = PhysicsCategory.player
    player.physicsBody?.collisionBitMask = PhysicsCategory.roof | PhysicsCategory.floor | PhysicsCategory.upperObstacle | PhysicsCategory.lowerObstacle | PhysicsCategory.scoreDetect
    player.physicsBody?.contactTestBitMask = PhysicsCategory.roof | PhysicsCategory.floor | PhysicsCategory.upperObstacle | PhysicsCategory.lowerObstacle | PhysicsCategory.scoreDetect
    player.physicsBody?.allowsRotation = false
    player.physicsBody?.affectedByGravity = true
    player.physicsBody?.isDynamic = false

}

// Create Background

func createTiles() {

    roof = SKSpriteNode(imageNamed: "Roof")
    roof.position = CGPoint(x: 0, y: self.frame.height / 2 - roof.size.height / 2)
    roof.zPosition = 1
    addChild(roof)

    roof.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Roof"), size: roof.size)
    roof.physicsBody?.categoryBitMask = PhysicsCategory.roof
    roof.physicsBody?.collisionBitMask = PhysicsCategory.player
    roof.physicsBody?.contactTestBitMask = PhysicsCategory.player
    roof.physicsBody?.allowsRotation = false
    roof.physicsBody?.affectedByGravity = false
    roof.physicsBody?.isDynamic = false

    floor = SKSpriteNode(imageNamed: "Floor")
    floor.position = CGPoint(x: 0, y: -self.frame.height / 2)
    floor.zPosition = 1
    addChild(floor)

    floor.physicsBody = SKPhysicsBody(texture: SKTexture(imageNamed: "Floor"), size: floor.size)
    floor.physicsBody?.categoryBitMask = PhysicsCategory.floor
    floor.physicsBody?.collisionBitMask = PhysicsCategory.player
    floor.physicsBody?.contactTestBitMask = PhysicsCategory.player
    floor.physicsBody?.allowsRotation = false
    floor.physicsBody?.affectedByGravity = false
    floor.physicsBody?.isDynamic = false

}

// Obstacle Spawn Rules

func createObstacle() {

    if (randomSelector() == 1) {
        lowerObstacle = SKSpriteNode(imageNamed: "Fire Barrel 1")
        upperObstacle = SKSpriteNode(imageNamed: "Fire Barrel 3")
        scoreDetect = SKSpriteNode(color: UIColor.red, size: CGSize(width: 32, height: frame.height))

        upperObstacle.position = CGPoint(x: self.frame.width / 2 + upperObstacle.size.width / 2, y: self.frame.height / 2 - upperObstacle.size.height / 2 + 12)
        lowerObstacle.position = CGPoint(x: self.frame.width / 2 + lowerObstacle.size.width / 2, y: -self.frame.height / 2 + lowerObstacle.size.height - 15)
        scoreDetect.position = CGPoint(x: self.frame.width / 2 + upperObstacle.size.width, y: 0)
    }
    else {
        if (randomSelector() == 2) {
            lowerObstacle = SKSpriteNode(imageNamed: "Fire Barrel 2")
            upperObstacle = SKSpriteNode(imageNamed: "Fire Barrel 2")
            scoreDetect = SKSpriteNode(color: UIColor.red, size: CGSize(width: 32, height: frame.height))

            upperObstacle.position = CGPoint(x: self.frame.width / 2 + upperObstacle.size.width / 2, y: self.frame.height / 2 - upperObstacle.size.height / 1.9)
            lowerObstacle.position = CGPoint(x: self.frame.width / 2 + lowerObstacle.size.width / 2, y: -self.frame.height / 2 + lowerObstacle.size.height / 1.5)
            scoreDetect.position = CGPoint(x: self.frame.width / 2 + upperObstacle.size.width, y: 0)
        }
        else {
            lowerObstacle = SKSpriteNode(imageNamed: "Fire Barrel 3")
            upperObstacle = SKSpriteNode(imageNamed: "Fire Barrel 1")
            scoreDetect = SKSpriteNode(color: UIColor.red, size: CGSize(width: 32, height: frame.height))

            upperObstacle.position = CGPoint(x: self.frame.width / 2 + upperObstacle.size.width / 2, y: self.frame.height / 2 - upperObstacle.size.height / 1.5 + 4)
            lowerObstacle.position = CGPoint(x: self.frame.width / 2 + lowerObstacle.size.width / 2, y: -self.frame.height / 2 + lowerObstacle.size.height / 1.75 + 7)
            scoreDetect.position = CGPoint(x: self.frame.width / 2 + upperObstacle.size.width, y: 0)
        }
    }

    lowerObstacle.zPosition = 2
    lowerObstacle.setScale(0.8)

    lowerObstacle.physicsBody = SKPhysicsBody(rectangleOf: lowerObstacle.size)
    lowerObstacle.physicsBody?.categoryBitMask = PhysicsCategory.lowerObstacle
    lowerObstacle.physicsBody?.collisionBitMask = PhysicsCategory.player
    lowerObstacle.physicsBody?.contactTestBitMask = PhysicsCategory.player
    lowerObstacle.physicsBody?.allowsRotation = false
    lowerObstacle.physicsBody?.affectedByGravity = false
    lowerObstacle.physicsBody?.isDynamic = false

    upperObstacle.zPosition = 2
    upperObstacle.setScale(0.8)

    upperObstacle.physicsBody = SKPhysicsBody(rectangleOf: upperObstacle.size)
    upperObstacle.physicsBody?.categoryBitMask = PhysicsCategory.upperObstacle
    upperObstacle.physicsBody?.collisionBitMask = PhysicsCategory.player
    upperObstacle.physicsBody?.contactTestBitMask = PhysicsCategory.player
    upperObstacle.physicsBody?.allowsRotation = false
    upperObstacle.physicsBody?.affectedByGravity = false
    upperObstacle.physicsBody?.isDynamic = false

    scoreDetect.physicsBody?.categoryBitMask = PhysicsCategory.scoreDetect
    scoreDetect.physicsBody?.collisionBitMask = PhysicsCategory.player
    scoreDetect.physicsBody?.contactTestBitMask = PhysicsCategory.player
    scoreDetect.physicsBody?.allowsRotation = false
    scoreDetect.physicsBody?.affectedByGravity = false
    scoreDetect.physicsBody?.isDynamic = false

    addChild(lowerObstacle)
    addChild(upperObstacle)
    addChild(scoreDetect)
    lowerObstacle.run(
        SKAction.sequence([
            SKAction.wait(forDuration: 6),
            SKAction.removeFromParent()
        ])
    )
    upperObstacle.run(
        SKAction.sequence([
            SKAction.wait(forDuration: 6),
            SKAction.removeFromParent()
        ])
    )
    scoreDetect.run(
        SKAction.sequence([
            SKAction.wait(forDuration: 6),
            SKAction.removeFromParent()
            ])
    )
}

// Create Spawn and Move Sequence

func repeatingSequence() {

    createObstacle()
    let moveLowerObstacle = SKAction.moveBy(x: -self.frame.width - lowerObstacle.size.width * 2, y: 0, duration: 5)
    lowerObstacle.run(moveLowerObstacle)
    let moveUpperObstacle = SKAction.moveBy(x: -self.frame.width - upperObstacle.size.width * 2, y: 0, duration: 5)
    upperObstacle.run(moveUpperObstacle)
    let moveScoreDetect = SKAction.moveBy(x: -self.frame.width - upperObstacle.size.width * 2, y: 0, duration: 5)
    scoreDetect.run(moveScoreDetect)

}

func createScoreLabel() {

    scoreLabel = SKLabelNode(fontNamed: "Arial")
    scoreLabel.fontSize = 22
    scoreLabel.position = CGPoint(x: 305, y: -638)
    scoreLabel.horizontalAlignmentMode = .center
    scoreLabel.verticalAlignmentMode = .center
    scoreLabel.text = "SCORE: \(scoreValue)"
    scoreLabel.fontColor = UIColor.white
    scoreLabel.zPosition = 4

    addChild(scoreLabel)

}

func didBegin(_ contact: SKPhysicsContact) {
    let firstBody = contact.bodyA
    let secondBody = contact.bodyB

    if firstBody.categoryBitMask == PhysicsCategory.scoreDetect && secondBody.categoryBitMask == PhysicsCategory.player || firstBody.categoryBitMask == PhysicsCategory.player && secondBody.categoryBitMask == PhysicsCategory.scoreDetect {
            scoreValue += 1
    }
}

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {

    player.physicsBody?.isDynamic = true
    let impulse = CGVector(dx: 0, dy: 200)
    player.physicsBody?.velocity = CGVector(dx: 0, dy: 0)
    player.physicsBody?.applyImpulse(impulse)

}

override func update(_ currentTime: TimeInterval) {

}

}

最佳答案

您正在正确更新 scoreValue 属性。但是,您还需要根据 scoreValue 的新值相应地更新 scoreLabel 中显示的内容。

所以替换这个

var scoreValue = Int()

有了这个

var scoreValue = Int() {
    didSet {
        scoreLabel.text = self.scoreValue.description
    }
}

现在每次 scoreValue 更改时,scoreLabel 都会自动更新。

关于Swift 3 更新带有递增整数的标签节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40506867/

相关文章:

swift - 使用计时器与更新来运行游戏 SpriteKit

使用自动布局快速增长 UITextView

json - 使用 SwiftyJSON 处理 Alamofire 异步请求

ios - SpriteKit 中的垂直无限滚动背景

swift - 确定哪个 Sprite 节点被击中

ios - 检查场景中的位置是否被 Sprite 占用

IOS 应用程序崩溃仅在 Release模式下发生?

swift - 如何在 macOS 上为 Linux 构建 swift 可执行文件

ios - 为不同语言的项目添加两个 Storyboard

ios - 我的节点没有发生冲突