我在制作无限卷轴时遇到问题。谷歌的结果表明,我必须使用效率低下的代码,因为我在模拟器和iPhone 5(物理设备)上获得了大约14-15 FPS,我得到了相同的结果。我希望有一些提高我的代码效率的技巧。合并功能可能呢?缩小图像并缩放图像? 当前的背景图片是1136x750。 平台大约是200x75。
import SpriteKit
class GameScene: SKScene, SKPhysicsContactDelegate {
let screenSize: CGRect = UIScreen.mainScreen().bounds
let backgroundVelocity : CGFloat = 6.0
override func didMoveToView(view: SKView) {
/* Setup your scene here */
self.backgroundColor = SKColor.whiteColor()
self.initializingScrollingBackground()
self.startPlatforms()
// Making self delegate of physics world
self.physicsWorld.gravity = CGVectorMake(0, 0)
self.physicsWorld.contactDelegate = self
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
self.moveBackground()
self.movePlatforms()
}
func startPlatforms(){
for var n = 0; n < 1000; ++n {
let plat = SKSpriteNode(imageNamed: "platform")
plat.position = CGPoint(x: n * (Int(plat.size.width)+125), y: 90)
plat.anchorPoint = CGPointZero
plat.name = "platform"
self.addChild(plat)
}
}
func movePlatforms() {
self.enumerateChildNodesWithName("platform", usingBlock: { (node, stop) -> Void in
if let plat = node as? SKSpriteNode {
plat.position = CGPoint(x: plat.position.x - self.backgroundVelocity, y: plat.position.y)
if(plat.position.x <= -200 ){
node.removeFromParent()
}
}
})
}
func initializingScrollingBackground() {
for var index = 0; index < 2; ++index {
let bg = SKSpriteNode(imageNamed: "bg")
bg.position = CGPoint(x: index * Int(bg.size.width), y: -55)
bg.anchorPoint = CGPointZero
bg.name = "background"
self.addChild(bg)
}
}
func moveBackground() {
self.enumerateChildNodesWithName("background", usingBlock: { (node, stop) -> Void in
if let bg = node as? SKSpriteNode {
bg.position = CGPoint(x: bg.position.x - self.backgroundVelocity, y: bg.position.y)
// Checks if bg node is completely scrolled off the screen, if yes, then puts it at the end of the other node.
if bg.position.x <= -bg.size.width {
bg.position = CGPointMake(bg.position.x + bg.size.width * 2, bg.position.y)
}
}
})
}
}
答案 0 :(得分:4)
写游戏时要记住的一个基本事实:
您想要从更新方法运行的每个代码(所以每帧) 必须快。
现在,让我们来看看你的代码。
如果你有一堆节点移动到一个节点,而不是手动移动每个节点,你应该为它们添加一个共同的parent
,然后只移动parent
。
所以这个
func startPlatforms(){
for var n = 0; n < 1000; ++n {
let plat = SKSpriteNode(imageNamed: "platform")
plat.position = CGPoint(x: n * (Int(plat.size.width)+125), y: 90)
plat.anchorPoint = CGPointZero
plat.name = "platform"
self.addChild(plat)
}
}
变成这个
private let platformParent = SKNode()
func createPlatforms() {
self.addChild(platformParent)
for n in 0...999 {
let plat = SKSpriteNode(imageNamed: "platform")
plat.position = CGPoint(x: n * (Int(plat.size.width)+125), y: 90)
plat.anchorPoint = CGPointZero
plat.name = "platform"
platformParent.addChild(plat)
}
}
现在您不需要移动每个平台,您可以运行仅移动父级的SKAction
。 children
将自动关注他。
所以这个
func movePlatforms() {
self.enumerateChildNodesWithName("platform", usingBlock: { (node, stop) -> Void in
if let plat = node as? SKSpriteNode {
plat.position = CGPoint(x: plat.position.x - self.backgroundVelocity, y: plat.position.y)
if(plat.position.x <= -200 ){
node.removeFromParent()
}
}
})
}
变成这个
// to be called only once!
func beginMovingParentPlatform() {
let moveToLeft = SKAction.moveToX(-200, duration: 5) // please change the 2 params (-200 and 5) as you need
self.platformParent.runAction(moveToLeft) {
self.removeAllChildren()
}
}
当然这个
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
self.moveBackground()
self.movePlatforms()
}
变成这个
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
self.moveBackground()
// self.movePlatforms()
}
现在你的代码应该更快。
您可以将相同的逻辑应用于moveBackground
。
请记住,不要手动移动节点。使用SKActions
,它们比您(或我)可以编写的代码更加优化。