Swift 3: класс работает неправильно

Итак, у меня есть класс с именем FlashyPaddleEffect, Я также упоминаю это в другом классе, GameScene, но он не применяет никакого эффекта, который должен. Весло должно мигать синим и белым цветами, но оно просто остается белым. Весло также должно потерять свое физическое тело, когда оно синее.

Если вам нужна какая-либо другая информация, не стесняйтесь спрашивать.

ПРИМЕЧАНИЕ. Могут быть проблемы с кодом, который я дал (из-за отступов довольно сложно сделать код с отступом 4 пробела в каждой строке, извините).

import SpriteKit
import GameplayKit

class FlashyPaddleEffect {

    var node = SKSpriteNode()
    var ballNode = SKSpriteNode()
    var updateTimer: Timer? = nil

    var timer: Timer? = nil

    @objc func changeNodeColor() {

        switch node.color {

        case SKColor.blue: node.color = SKColor.white
        case SKColor.white: node.color = SKColor.blue

        default: _ = 1 + 2

        }

    }

    @objc func update() //I used the objc prefix to silence the warning the selectors of the timers produced. {

        let previousPhysicsBody = node.physicsBody

        if node.color == SKColor.blue {

            node.physicsBody = nil

        }

        node.physicsBody = previousPhysicsBody

    }

    func make(applyEffectTo: SKSpriteNode, ball: SKSpriteNode) {

        node = applyEffectTo
        ballNode = ball

        timer = Timer.scheduledTimer(timeInterval: 0.6, target: self, selector: #selector(changeNodeColor), userInfo: nil, repeats: true)
        updateTimer = Timer.scheduledTimer(timeInterval: 0.3, target: self,      selector: #selector(update), userInfo: nil, repeats: true)

        _ = node
        _ = timer

    }

}

class GameScene: SKScene {

    var ball =  SKSpriteNode()
    var player = SKSpriteNode()
    var enemy = SKSpriteNode()

    var scores = [0, 0]
    var initScores = [0, 0]
    var  scoreLabels: [SKLabelNode]? = nil

    let playLabel = SKLabelNode()
    let timeLabel = SKLabelNode()
    let timeUpLabel = SKLabelNode()

    var secondsLeft: Int = 180
    var initialTime: Int? = nil

    var timer = Timer()

    var amountOfPauseMenuCloses = 0

    var resultsLabel = SKLabelNode()

    let flashEffect = FlashyPaddleEffect() //I define a variable to mention the class easier later on.

    override func didMove(to view: SKView) {

        //Initialize nodes of the scene editor.
        ball =  self.childNode(withName: "Ball") as! SKSpriteNode
        player = self.childNode(withName: "PPaddle") as! SKSpriteNode
        enemy = self.childNode(withName: "EPaddle") as! SKSpriteNode

        //Set styles for the Play Notification Label (referred to as PNL later)
        playLabel.position = CGPoint(x: 0, y: 0)
        playLabel.text = "Tap anywhere to play."
        playLabel.name = "playLabel"

        //Set styles for the Timer Label (referred to as Timer later)
        timeLabel.position = CGPoint(x: 90, y: 0)
        timeLabel.text = String(secondsLeft)

        //Doing manipulations connected with scores here.
        scores = [0, 0]
        initScores = scores
        scoreLabels = [self.childNode(withName: "PScoreLabel") as! SKLabelNode, self.childNode(withName: "EScoreLabel") as! SKLabelNode]

        //Create a border for our ball to bounce off.
        let border = SKPhysicsBody(edgeLoopFrom: self.frame)
        border.friction = 0
        border.restitution = 1
        border.linearDamping = 0
        border.angularDamping = 0
        self.physicsBody = border

       //To avoid the ball's damping.
       ball.physicsBody?.linearDamping = 0
       ball.physicsBody?.angularDamping = 0

       showPause() //Show the (pause) menu at the beginning

       //Set a variable to refer to as a time standard later.
       initialTime = secondsLeft

       //The game timer.
       timer = Timer.scheduledTimer(timeInterval: 1.0, target: self, selector: #selector(reduceSecondFromTimer), userInfo: nil, repeats: true)

        flashEffect.make(applyEffectTo: player, ball: ball) //This is where I reference the class in another class. 

    }

    //A function to show the (pause) menu.
    func showPause(hideNodes: Bool = true) {

        self.addChild(playLabel)

        if hideNodes == true {

            ball.removeFromParent()
            player.removeFromParent()
            enemy.removeFromParent()
            scoreLabels?[0].removeFromParent()
            scoreLabels?[1].removeFromParent()

        }

    }

    override func update(_ currentTime: TimeInterval) {

        var alreadyChangedTextLabel = false

        for i in scoreLabels! {

            if i.name == "PScoreLabel" {i.text = String(scores[0])}
            if i.name == "EScoreLabel" {i.text = String(scores[1])}


        }

        if ball.position.y <= player.position.y {scores[1] += 1}
        if ball.position.y >= enemy.position.y {scores[0] += 1}

        if secondsLeft == 0 {

            showPause(hideNodes: false)

            if alreadyChangedTextLabel == false {

                timeUpLabel.text = "TIME UP! \(whoIsWinning(scores: scores)) won!"
                alreadyChangedTextLabel = true

            }

            timeUpLabel.name = "timeUpLabel"
            timeUpLabel.position = CGPoint(x: 0, y: 180)

            if !(self.children.contains(timeUpLabel)) {

                self.addChild(timeUpLabel)

            }

            timeLabel.removeFromParent()

        }

        if self.children.contains(playLabel) {

            secondsLeft = initialTime!

        }

        timeLabel.text = String(secondsLeft)

        let alignWithBall = SKAction.move(to: CGPoint(x: ball.position.x, y: enemy.position.y), duration: 0.8)
    enemy.run(alignWithBall)

    }

    func initGame() {

        //Initializing process for every game.

        scores = initScores
        ball.position = CGPoint(x: 0, y: 0)

        if amountOfPauseMenuCloses == 1  {ball.physicsBody?.applyImpulse(CGVector(dx: 15, dy: 15))}

        secondsLeft = initialTime!
        timeLabel.text = String(secondsLeft)

    }



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

        for childNode in self.children {

            if childNode.name == "playLabel" {

                if self.children.contains(playLabel) {

                    playLabel.removeFromParent()

                }


                if !(self.children.contains(player)) {

                    self.addChild(player)

                }

                if !(self.children.contains(enemy)) {

                    self.addChild(enemy)

                }

                if !(self.children.contains(ball)) {

                    self.addChild(ball)

                }

                if !(self.children.contains((scoreLabels?[0])!)) {

                    self.addChild((scoreLabels?[0])!)

                }

                if !(self.children.contains((scoreLabels?[1])!)) {

                    self.addChild((scoreLabels?[1])!)    
                }

                if !(self.children.contains(timeLabel)) {

                    self.addChild(timeLabel)

                }

                if self.children.contains(timeUpLabel) {

                    timeUpLabel.removeFromParent()

                }

                amountOfPauseMenuCloses += 1

                initGame()

            }

        }

    }




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

    for t in touches {

            if self.nodes(at: t.location(in: self)).contains(player) {player.position.x = t.location(in: self).x}

        }

    }

    func reduceSecondFromTimer() {

        secondsLeft -= 1

    }

    func whoIsWinning(scores: Array<Int>) -> String {

        var r: String? = nil

        if scores[0] >= scores[1] {

            r = "You"

        }

        if scores[1] >= scores[0] {

            r = "Enemy"

        }

        return r!

    }

}

Большое спасибо за ответы. PS Это мой первый вопрос, поэтому не судите меня строго.

1 ответ

1) не использовать NSTimer использование SKAction, Я вижу, как ты это делаешь, ты ставишь таймер за таймером, это плохо.

2) У вас нет глобальной переменной temp (в нашем случае это node), это затрудняет чтение кода

3) Не удаляйте свое физическое тело, просто удалите категорию.

func make(applyEffectTo: SKSpriteNode, ball: SKSpriteNode) {

    ballNode = ball
    let blue = SKAction.colorize(with SKColor.blue, colorBlendFactor: 1.0, duration sec: 0)
    let white = SKAction.colorize(with SKColor.white, colorBlendFactor: 1.0, duration sec: 0)
    let wait = SKAction.wait(for:0.6)
    let turnOnPhysics = SKAction.run({applyEffectTo.physicsBody?.categoryBitmask = #######})
    let turnOffPhysics = SKAction.run({applyEffectTo.physicsBody?.categoryBitmask = 0})
    let seq = [blue, turnOffPhysics,wait,white,turnOnPhysics,wait]
    let repeat = SKAction.repeatForever(seq)
    applyEffectTo.run(repeat, withKey:"flashing")

}

Примечание: я понятия не имею, что вы categoryBitmask нужно заполнить

Другие вопросы по тегам