简体   繁体   English

斯威夫特变量不持有价值或以某种方式重置自己

[英]Swift variable not holding value or resetting itself somehow

I am trying to keep score in a game which has different point values associated with different things. 我试图在具有与不同事物相关的不同得分的游戏中保持得分。 The user has to touch things in the game to get the points. 用户必须触摸游戏中的东西才能获得积分。 However the score is not being calculated accurately. 但是,分数无法准确计算。

I have determined that the score associated which each element in the game is being stored properly in a variable called ballValue . 我确定与游戏中每个元素相关的分数已正确存储在名为ballValue的变量中。 The variable currentScore is used to hold the score and then I'm using a SKLabelNode to display the value of currentScore . 变量currentScore用于保存得分,然后使用SKLabelNode显示currentScore的值。

currentScore is initialized with a value of 0 and is updated with its current value plus ballValue when a user touches a ball. 当用户触摸球时, currentScore初始化为0值,并用其当前值加上ballValue更新。

Update to show code and context 更新以显示代码和上下文

class ChallengeScene: SKScene, GKGameCenterControllerDelegate {

    // MARK: Ball Data
    var randomBallType : Int = 0
    var ballValue : Int = 0

    // MARK: HUD
    var scoreLabel = SKLabelNode(fontNamed: "Impact")
    var timeLabel = SKLabelNode(fontNamed: "Impact")

    var currentScore : Int = 0 {
        didSet {
            self.scoreLabel.text = "\(self.currentScore)"
            GameHandler.sharedInstance.score = currentScore
        }
    }

    // MARK: Initial Setup
    func createHUD() {
    ... UNRELATED HUD STUFF...
        currentScore = 0
    }

    // MARK: Gameplay Setup
    func createBall(forTrack track: Int) {
        setupTracks()

        randomBallType = GKRandomSource.sharedRandom().nextInt(upperBound: 9)

        switch randomBallType {
        case 0:
            player = SKSpriteNode(imageNamed: "blueOne")
            ballSpeed = 0.008
            ballValue = 1
        case 1:
            player = SKSpriteNode(imageNamed: "minusThree")
            ballSpeed = 0.008
            ballValue = -3
        case 2:
            player = SKSpriteNode(imageNamed: "minusFive")
            ballSpeed = 0.008
            ballValue = -5
        case 3:
            player = SKSpriteNode(imageNamed: "purpleThree")
            ballSpeed = 0.008
            ballValue = 3
        case 4:
            player = SKSpriteNode(imageNamed: "greenFive")
            ballSpeed = 0.008
            ballValue = 5
        case 5:
            player = SKSpriteNode(imageNamed: "blackTen")
            ballSpeed = 0.008
            ballValue = 10
        default:
            player = SKSpriteNode(imageNamed: "blueOne")
            ballSpeed = 0.008
            ballValue = 1
        }

        player?.name = "BALL"
        player?.size = CGSize(width: 100, height: 100)
        player?.physicsBody?.linearDamping = 0

        ...UNRELATED BALL STUFF...

        self.addChild(player!)
    }

    // MARK: Overrides
    override func didMove(to view: SKView) {

        createHUD()
        launchGameTimer()

        self.run(SKAction.repeatForever(SKAction.sequence([SKAction.run {
            self.createBall(forTrack: self.track)
            }, SKAction.wait(forDuration: 1)])))

    }

    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches {
            let location = touch.location(in: self)
            let node = self.nodes(at: location).first

            if node?.name == "BALL" {
                currentScore = currentScore + ballValue
                node?.removeFromParent()
            }
        }

    }


    override func update(_ currentTime: TimeInterval) {

        // GAME TIMER RELATED STUFF

    }
}

I think I know where the problem happens (in the touches override), I just don't understand why it is happening. 我想我知道问题发生在哪里(触摸覆盖),我只是不明白为什么会发生。 If you could help in anyway that would be awesome 如果您能以任何方式提供帮助,那将很棒

You have a single ballValue property. 您只有一个ballValue属性。 Every time you spawn a new ball, you set ballValue as appropriate for that newly-created ball . 每次生成新球时, ballValue新创建的ball设置适当的ballValue What about all the other existing balls? 那其他所有现有的球呢? A touch on any of them will also be worth that same ballValue . 触摸其中任何一个也将值得同一个ballValue

When a ball is touched, you need to know the proper value for the touched ball , which may be different than the value of the most-recently-created ball. 触摸球时,您需要知道所触摸球的正确值, 值可能与最近创建的球的值不同。 What you probably want to do is create a subclass of SKSpriteNode that represents a ball, and holds its own value: 您可能想要做的是创建一个SKSpriteNode的子类,该子类表示一个球并保留其自己的值:

class BallNode: SKSpriteNode {
    let value: Int

    init(imageName: String, speed: CGFloat, value: Int) {
        let texture = SKTexture(imageNamed: imageName)
        self.value = value
        super.init(texture: texture, color: .init(white: 1, alpha: 0), size: texture.size())
        self.speed = speed
    }

    required init(coder decoder: NSCoder) { fatalError() }
}

Create the balls like this: 创建这样的球:

func createBall(forTrack track: Int) {

// setupTracks() // setupTracks()

    randomBallType = GKRandomSource.sharedRandom().nextInt(upperBound: 9)

    let ball: BallNode
    switch randomBallType {
    case 0: ball = BallNode(imageNamed: "blueOne", speed: 0.008, value: 1)
    case 1: ball = BallNode(imageNamed: "minusThree", speed: 0.008, value: -3)
    case 2: ball = BallNode(imageNamed: "minusFive", speed: 0.008, value: -5)
    // etc.
    }

    ball.name = "BALL"
    ball.size = CGSize(width: 100, height: 100)
    ball.physicsBody?.linearDamping = 0

    // ...UNRELATED BALL STUFF...

    self.addChild(ball)
}

Then, to handle a touch, use the touched ball's value to update the score: 然后,要处理触摸,请使用触摸的球的值来更新得分:

override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    for touch in touches {
        let location = touch.location(in: self)
        if let ball = self.nodes(at: location).flatMap({ $0 as? BallNode }).first {
            currentScore += ball.value
            ball.removeFromParent()
        }
    }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM