SpriteKit CPU使用率 - 非常高

时间:2017-03-31 14:44:20

标签: ios swift sprite-kit

我有一个表视图,在其中一个单元格中有一个UIView,它承载一个SKScene,它有几个云从右到左以不同的速度浮动。 FPS:60,屏幕上总是出现不超过5个节点。 但CPU使用率仍然很高。我该怎么办呢?

import UIKit
import SpriteKit


class AnimationView: UIViewController {


override func viewDidLoad() {
    super.viewDidLoad()

    let scene = CloudsScene(size: view.bounds.size)
    let skView = view as! SKView
    skView.showsFPS = false
    skView.showsNodeCount = false
    skView.ignoresSiblingOrder = true
    scene.scaleMode = .resizeFill
    skView.presentScene(scene)
    }
}

SKScene课程:

import SpriteKit

func + (left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x + right.x, y: left.y + right.y)}

func - (left: CGPoint, right: CGPoint) -> CGPoint {
return CGPoint(x: left.x - right.x, y: left.y - right.y)}

func * (point: CGPoint, scalar: CGFloat) -> CGPoint {
return CGPoint(x: point.x * scalar, y: point.y * scalar)}

func / (point: CGPoint, scalar: CGFloat) -> CGPoint {
return CGPoint(x: point.x / scalar, y: point.y / scalar)}

#if !(arch(x86_64) || arch(arm64))
func sqrt(a: CGFloat) -> CGFloat {
    return CGFloat(sqrtf(Float(a)))
}
#endif

extension CGPoint {
func length() -> CGFloat {
    return sqrt(x*x + y*y)
}

func normalized() -> CGPoint {
    return self / length()
}
}

struct PhysicsCategory {
static let None      : UInt32 = 0
static let All       : UInt32 = UInt32.max
static let Cloud   : UInt32 = 0b1       // 1
static let Projectile: UInt32 = 0b10      // 2
}

class CloudsScene: SKScene, SKPhysicsContactDelegate {

// 1
let sun = SKSpriteNode(imageNamed: "Sun")
var cloudsDestroyed = 0
var background = SKSpriteNode(imageNamed: "Mountains_Bkgd")


override func didMove(to view: SKView) {
    backgroundColor = SKColor.white

    background.zPosition = 0
    background.size = CGSize(width: frame.size.width, height: frame.size.height)
    background.position = CGPoint(x: frame.size.width / 2, y: frame.size.height / 2)
    addChild(background)

    sun.position = CGPoint(x: size.width * 0.1, y: size.height * 0.5)
    sun.zPosition = 1
    addChild(sun)

    physicsWorld.speed = 0.9999
    physicsWorld.gravity = CGVector.zero
    physicsWorld.contactDelegate = self

    run(SKAction.repeatForever(
        SKAction.sequence([
            SKAction.run(addCloud),
            SKAction.wait(forDuration: 6)
            ])
    ))

}

func random() -> CGFloat {
    return CGFloat(Float(arc4random()) / 0xFFFFFFFF)
}

func random(min: CGFloat, max: CGFloat) -> CGFloat {
    return random() * (max - min) + min
}

func addCloud() {

    //print("add cloud")

    //Choose random cloud out of 6 images
    let randomNumber = arc4random_uniform(5)
    let imageName = "Cloud\(randomNumber)"

    // Create sprite
    let cloud = SKSpriteNode(imageNamed: imageName)

    cloud.physicsBody = SKPhysicsBody(rectangleOf: cloud.size) // 1
    cloud.physicsBody?.isDynamic = true // 2
    cloud.physicsBody?.categoryBitMask = PhysicsCategory.Cloud // 3
    cloud.physicsBody?.contactTestBitMask = PhysicsCategory.Projectile // 4
    cloud.physicsBody?.collisionBitMask = PhysicsCategory.None // 5

    // Determine where to spawn the cloud along the Y axis
    let actualY = random(min: size.height/2, max: size.height - cloud.size.height/2)
    //print(actualY)

    // Position the cloud slightly off-screen along the right edge,
    // and along a random position along the Y axis as calculated above
    cloud.position = CGPoint(x: size.width + cloud.size.width/2, y: actualY)

    cloud.zPosition = 2
    // Add the cloud to the scene
    addChild(cloud)

    // Determine speed of the cloud
    let actualDuration = random(min: CGFloat(12.0), max: CGFloat(24.0))

    // Create the actions
    let actionMove = SKAction.move(to: CGPoint(x: -cloud.size.width/2, y: actualY), duration: TimeInterval(actualDuration))
    let actionMoveDone = SKAction.removeFromParent()

    let loseAction = SKAction.run() {
        let reveal = SKTransition.flipHorizontal(withDuration: 0.5)
    }
    cloud.run(SKAction.sequence([actionMove, loseAction, actionMoveDone]))

}

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

    print("touches Ended")

    //run(SKAction.playSoundFileNamed("pew-pew-lei.caf", waitForCompletion: false))

    // 1 - Choose one of the touches to work with
    guard let touch = touches.first else {
        return
    }
    let touchLocation = touch.location(in: self)

    // 2 - Set up initial location of projectile
    let projectile = SKSpriteNode(imageNamed: "location")
    projectile.position = sun.position

    projectile.physicsBody = SKPhysicsBody(circleOfRadius: projectile.size.width/2)
    projectile.physicsBody?.isDynamic = true
    projectile.physicsBody?.categoryBitMask = PhysicsCategory.Projectile
    projectile.physicsBody?.contactTestBitMask = PhysicsCategory.Cloud
    projectile.physicsBody?.collisionBitMask = PhysicsCategory.None
    projectile.physicsBody?.usesPreciseCollisionDetection = true

    // 3 - Determine offset of location to projectile
    let offset = touchLocation - projectile.position

    // 4 - Bail out if you are shooting down or backwards
    if (offset.x < 0) { return }

    // 5 - OK to add now - you've double checked position
    addChild(projectile)

    // 6 - Get the direction of where to shoot
    let direction = offset.normalized()

    // 7 - Make it shoot far enough to be guaranteed off screen
    let shootAmount = direction * 1000

    // 8 - Add the shoot amount to the current position
    let realDest = shootAmount + projectile.position

    // 9 - Create the actions
    let actionMove = SKAction.move(to: realDest, duration: 2.0)
    let actionMoveDone = SKAction.removeFromParent()
    projectile.run(SKAction.sequence([actionMove, actionMoveDone]))

}

func projectileDidCollideWithCloud(projectile: SKSpriteNode, cloud: SKSpriteNode) {
    print("Hit")
    projectile.removeFromParent()
    cloud.removeFromParent()

    cloudsDestroyed += 1
    if (cloudsDestroyed > 30) {
        let reveal = SKTransition.flipHorizontal(withDuration: 0.5)

    }
}

func didBegin(_ contact: SKPhysicsContact) {

    print("did Begin")

    // 1
    var firstBody: SKPhysicsBody
    var secondBody: SKPhysicsBody
    if contact.bodyA.categoryBitMask < contact.bodyB.categoryBitMask {
        firstBody = contact.bodyA
        secondBody = contact.bodyB
    } else {
        firstBody = contact.bodyB
        secondBody = contact.bodyA
    }

    // 2
    if ((firstBody.categoryBitMask & PhysicsCategory.Cloud != 0) &&
        (secondBody.categoryBitMask & PhysicsCategory.Projectile != 0)) {
        if let cloud = firstBody.node as? SKSpriteNode, let
            projectile = secondBody.node as? SKSpriteNode {
            projectileDidCollideWithCloud(projectile: projectile, cloud: cloud)
        }
    }

}

}

enter image description here enter image description here

0 个答案:

没有答案