微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

SpriteKit Sprite 在应该移动时冻结在屏幕上

如何解决SpriteKit Sprite 在应该移动时冻结在屏幕上

即使屏幕上的其他精灵会继续您在屏幕上水平移动,精灵也会经常在屏幕上冻结而不移动。我相信这可能与 element.run(SKAction.moveBy(x: moveSpeedFloat,y: 0,duration: 0.25))

我更新精灵是否移动得太快了?

有没有更好的方法来更新精灵运动?

谢谢,感谢帮助

GameScene 类:

import SpriteKit
import GameplayKit

class GameScene: SKScene {
    
    var gamescore: SKLabelNode!
    var countdownLabel: SKLabelNode!
    var bulletsLeftLabel: SKLabelNode!
    var reloadButton: UIButton!
    
    var slots = [TargetSlot]()
    
    let brownDuckTexture = SKTexture(imageNamed: "brownduck")
    let duckTexture = SKTexture(imageNamed: "duck")
    let frogTexture = SKTexture(imageNamed: "frog")
    let crocodileTexture = SKTexture(imageNamed: "crocodile")
    let posionAppleTexture = SKTexture(imageNamed: "posionapple")
    let targetTexture = SKTexture(imageNamed: "target")
    
    let rowdistribution = GKShuffleddistribution(lowestValue: 1,highestValue: 3)
    let texturedistribution = GKShuffleddistribution(lowestValue: 1,highestValue: 6)
    let moveSpeeddistribution = GKRandomdistribution(lowestValue: 50,highestValue: 100)
    
    var gameInProgress = true
    
    var score = 0 {
        didSet {
            gamescore.text = "score: \(score)"
        }
    }
    
    var bulletsLeft = 6 {
        didSet {
            bulletsLeftLabel.text = "Bullets: \(bulletsLeft)"
        }
    }
    
    var timer:Timer?
    var timeLeft = 60 {
        didSet {
            countdownLabel.text = "Time: \(timeLeft)"
            if timeLeft <= 0 {
                gameOver()
            }
        }
    }
    
    override func didMove(to view: SKView) {
        
        let background = SKSpriteNode(imageNamed: "251204.png")
        background.position = CGPoint(x: 512,y: 384)
        background.blendMode = .replace
        background.zPosition = -1
        addChild(background)
        
        gamescore = SKLabelNode(fontNamed: "GillSans-Bold")
        gamescore.text = "score: 0"
        gamescore.position = CGPoint(x: 8,y: 8)
        gamescore.horizontalAlignmentMode = .left
        gamescore.fontSize = 48
        gamescore.zPosition = 1
        addChild(gamescore)
        
        countdownLabel = SKLabelNode(fontNamed: "GillSans-Bold")
        countdownLabel.text = "Time: 0"
        countdownLabel.position = CGPoint(x: 250,y: 8)
        countdownLabel.horizontalAlignmentMode = .left
        countdownLabel.fontSize = 48
        countdownLabel.zPosition = 1
        addChild(countdownLabel)
        
        bulletsLeftLabel = SKLabelNode(fontNamed: "GillSans-Bold")
        bulletsLeftLabel.text = "Bullets: 6"
        bulletsLeftLabel.position = CGPoint(x: 475,y: 8)
        bulletsLeftLabel.horizontalAlignmentMode = .left
        bulletsLeftLabel.fontSize = 48
        bulletsLeftLabel.zPosition = 1
        addChild(bulletsLeftLabel)
        
        dispatchQueue.main.asyncAfter(deadline: .Now() + 1) {
            [weak self] in
            self?.moveTargets()
        }
        dispatchQueue.main.asyncAfter(deadline: .Now() + 1) {
            [weak self] in
            self?.createEnemy()
        }
        
        timer = Timer.scheduledTimer(timeInterval: 1.0,target: self,selector: #selector(onTimerFires),userInfo: nil,repeats: true)
    }
    
    override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) {
        if bulletsLeft <= 0 {
            return
        }
        guard let touch = touches.first else { return }
        let location = touch.location(in: self)
        let tappednodes = nodes(at: location)
        
        bulletsLeft -= 1
        
        for node in tappednodes {
            guard let targetSlot = node.parent as? TargetSlot else { return }
            
            if node.name == "good" {
                score += 1
            } else if node.name == "bad" {
                score -= 1
            }
            
            targetSlot.removeEnemy()
            targetSlot.removeFromParent()
            //            print(slots.count)
            let itemToRemove = targetSlot
            if let index = slots.firstIndex(of: itemToRemove){
                slots.remove(at: index)
            }
            //            print(slots.count)
            
        }
    }
    
    func createTarget(at position: CGPoint,row: Int,texture: SKTexture,trait: String,scale: CGFloat,moveSpeed: Int){
        let slot = TargetSlot()
        //        print(position,row,texture,trait,scale)
        slot.configure(at: position,row: row,texture: texture,trait: trait,scale: scale,moveSpeed: moveSpeed)
        addChild(slot)
        slots.append(slot)
    }
    
    func createEnemy(){
        var texture: SKTexture
        var trait: String
        var scale: CGFloat
        var moveSpeed: Int
        //        let randomNum = Int.random(in: 1...6)
        let randomNum = texturedistribution.nextInt()
        switch randomNum {
        case 1:
            texture = brownDuckTexture
            trait = "good"
            scale = 0.2
        case 2:
            texture = duckTexture
            trait = "good"
            scale = 0.2
        case 3:
            texture = frogTexture
            trait = "good"
            scale = 0.4
        case 4:
            texture = crocodileTexture
            trait = "bad"
            scale = 0.3
        case 5:
            texture = posionAppleTexture
            trait = "bad"
            scale = 0.2
        case 6:
            texture = targetTexture
            trait = "bad"
            scale = 0.2
        default:
            return
        }
        
        let randomNumber = rowdistribution.nextInt()
        moveSpeed = moveSpeeddistribution.nextInt()
        switch randomNumber {
        case 1:
            createTarget(at: CGPoint(x: -50,y: 100),row: 1,moveSpeed: moveSpeed)
        case 2:
            createTarget(at: CGPoint(x: 550,y: 200),row: 2,moveSpeed: moveSpeed)
        case 3:
            createTarget(at: CGPoint(x: -50,y: 300),row: 3,moveSpeed: moveSpeed)
        default:
            return
        }
        //        print("created at: \(randomNumber)")
        
        if gameInProgress == true {
            dispatchQueue.main.asyncAfter(deadline: .Now() + 1.5) {
                [weak self] in
                self?.createEnemy()
            }
        }
    }
    
    func moveTargets(){
        for (index,element) in slots.enumerated() {
            if element.position .x >= 1150 || element.position .x <= -650 {
                element.removeEnemy()
                element.removeFromParent()
                slots.remove(at: index)
            } else {
                let moveSpeed: Int = element.moveSpeed
                let moveSpeednegative: Int = -moveSpeed
                let moveSpeedFloat = CGFloat(moveSpeed)
                let moveSpeedFloatNegative = CGFloat(moveSpeednegative)
                
                if element.row == 1 || element.row == 3 {
                    element.run(SKAction.moveBy(x: moveSpeedFloat,duration: 0.25))
                } else {
                    element.run(SKAction.moveBy(x: moveSpeedFloatNegative,duration: 0.25))
                }
            }
        }
        
        if gameInProgress == true {
            dispatchQueue.main.asyncAfter(deadline: .Now() + 0.25) {
                [weak self] in
                self?.moveTargets()
            }
        }
    }
    
    @objc func onTimerFires() {
        timeLeft -= 1
        
        if timeLeft <= 0 {
            timer?.invalidate()
            timer = nil
        }
    }
    
    func gameOver() {
        gameInProgress = false
        
        let gameOver = SKSpriteNode(imageNamed: "gameOver")
        gameOver.position = CGPoint(x: 512,y: 384)
        gameOver.zPosition = 1
        addChild(gameOver)
        
        let finalscoreLabel = SKLabelNode(fontNamed: "GillSans-Bold")
        finalscoreLabel.position = CGPoint(x: 512,y: 300)
        finalscoreLabel.text = "Final score: \(score)"
        finalscoreLabel.fontSize = 48
        finalscoreLabel.zPosition = 1
        addChild(finalscoreLabel)
    }

    @objc func reloadBullets() {
        
        bulletsLeft = 6
        
    }
}

TargetSlot 类:

import UIKit
import SpriteKit

class TargetSlot: SKNode {
    var targetNode: SKSpriteNode!
    
    var row: Int!
    var texture: SKTexture!
    var trait: String!
    var scale: CGFloat!
    var moveSpeed: Int!
    

//    func configure(at position: CGPoint,triat: String,scale: CGFloat) {
    func configure(at position: CGPoint,moveSpeed: Int){
        self.position = position
        self.row = row
        self.texture = texture
        self.trait = trait
        self.scale = scale
        self.moveSpeed =  moveSpeed
//        print(position,triat,scale)
        targetNode = SKSpriteNode(texture: texture)
        targetNode.name = trait
        targetNode.setScale(scale)
        
        targetNode.position = position
        addChild(targetNode)
    }
    
    func removeEnemy() {
        targetNode.removeFromParent()
        targetNode.removeAllActions()
    }
}

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。