Swift 为什么应用程序在调用函数时会滞后很多
我正在构建一个游戏,它需要根据条件是否为真调用一个函数(从几个函数中选择)。出于游戏目的,条件每0.0001秒检查一次变量,但函数每4-6秒调用一次。我只是需要这个 每当我在一台设备上测试游戏时,我都会注意到该应用程序在某些时间滞后。我相信它是在函数被调用时发生的,但我不确定 这是一个SKAction,调用检查条件的函数:Swift 为什么应用程序在调用函数时会滞后很多,swift,sprite-kit,skspritenode,skaction,Swift,Sprite Kit,Skspritenode,Skaction,我正在构建一个游戏,它需要根据条件是否为真调用一个函数(从几个函数中选择)。出于游戏目的,条件每0.0001秒检查一次变量,但函数每4-6秒调用一次。我只是需要这个 每当我在一台设备上测试游戏时,我都会注意到该应用程序在某些时间滞后。我相信它是在函数被调用时发生的,但我不确定 这是一个SKAction,调用检查条件的函数: let triangle = SKAction.sequence([SKAction.run(obstaclesFunc),SKAction.wait(forDuration
let triangle = SKAction.sequence([SKAction.run(obstaclesFunc),SKAction.wait(forDuration: 0.0001)])
run(SKAction.repeatForever(triangle))
这是条件检查器:
func obstaclesFunc() {
GameScene.nextObstacle = Int(arc4random_uniform(6) + 1 )
if(GameScene.first == true){
GameScene.randomNum = 1
}
if (GameScene.pass == true){
number = GameScene.nextObstacle
print(number)
//Rectangle Call Function
if(GameScene.randomNum == 1){
sideRectangles()
//More code at bottom
}
我注意到最大的延迟发生在调用此函数时:
func sideRectangles() {
let rectangle1 = SKSpriteNode(imageNamed: "rectangleWalls")
let rectangle2 = SKSpriteNode(imageNamed: "rectangleWalls")
let rectangle3 = SKSpriteNode(imageNamed: "rectangleWalls")
let rectangleTexture = SKTexture(imageNamed: "rectangleWalls")
//Physics World
rectangle1.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle1.physicsBody?.categoryBitMask = PhysicsNumbering.rectangle_1
rectangle1.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle1.physicsBody?.affectedByGravity = false
rectangle1.physicsBody?.isDynamic = true
rectangle1.physicsBody?.collisionBitMask = 0
//Physics World
rectangle2.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle2.physicsBody?.categoryBitMask = PhysicsNumbering.rectangle_2
rectangle2.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle2.physicsBody?.affectedByGravity = false
rectangle2.physicsBody?.isDynamic = true
rectangle2.physicsBody?.collisionBitMask = 0
//Physics World
rectangle3.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle3.physicsBody?.categoryBitMask = PhysicsNumbering.rectangle_3
rectangle3.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle3.physicsBody?.affectedByGravity = false
rectangle3.physicsBody?.isDynamic = true
rectangle3.physicsBody?.collisionBitMask = 0
let moveDown = SKAction.moveTo(y: self.frame.minY - rectangle3.size.height / 2, duration: 2)
let moveDown2 = SKAction.moveTo(y: self.frame.minY - rectangle3.size.height / 2, duration: 3)
let moveDown3 = SKAction.moveTo(y: self.frame.minY - rectangle3.size.height / 2, duration: 4)
let removeNode = SKAction.removeFromParent()
rectangle1.position = CGPoint(x: self.frame.minX - rectangle3.size.height * 0.1, y: self.frame.maxY + rectangle3.size.width) //use 4.5 for the close one
rectangle2.position = CGPoint(x: self.frame.minX - rectangle3.size.width / 40 , y: self.frame.maxY + rectangle3.size.height) //use 4.5 for the close one
rectangle3.position = CGPoint(x: self.frame.midX - rectangle3.size.width / 1.55, y: self.frame.maxY + rectangle3.size.height * 1.8)
rectangle1.run(SKAction.sequence([moveDown,removeNode]))
rectangle2.run(SKAction.sequence([moveDown2,removeNode]))
rectangle3.run(SKAction.sequence([moveDown3,removeNode]))
//second set
let rectangle5 = SKSpriteNode(imageNamed: "rectangleWalls")
let rectangle6 = SKSpriteNode(imageNamed: "rectangleWalls")
let rectangle7 = SKSpriteNode(imageNamed: "rectangleWalls")
//Physics World
rectangle5.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle5.physicsBody?.categoryBitMask = PhysicsNumbering.rectangle_5
rectangle5.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle5.physicsBody?.affectedByGravity = false
rectangle5.physicsBody?.isDynamic = true
rectangle5.physicsBody?.collisionBitMask = 0
//Physics World
rectangle6.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle6.physicsBody?.categoryBitMask = PhysicsNumbering.rectangle_6
rectangle6.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle6.physicsBody?.affectedByGravity = false
rectangle6.physicsBody?.isDynamic = true
rectangle6.physicsBody?.collisionBitMask = 0
//Physics World
rectangle7.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle7.physicsBody?.categoryBitMask = PhysicsNumbering.rectangle_7
rectangle7.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle7.physicsBody?.affectedByGravity = false
rectangle7.physicsBody?.isDynamic = true
rectangle7.physicsBody?.collisionBitMask = 0
rectangle5.zPosition = 0
rectangle6.zPosition = 0
rectangle7.zPosition = 0
rectangle5.position = CGPoint(x: self.frame.maxX + rectangle3.size.height * 0.1, y: self.frame.maxY + rectangle3.size.width) //use 4.5 for the close one
rectangle6.position = CGPoint(x: self.frame.maxX + rectangle3.size.width / 40 , y: self.frame.maxY + rectangle3.size.height) //use 4.5 for the close one
rectangle7.position = CGPoint(x: self.frame.midX + rectangle3.size.width / 1.55, y: self.frame.maxY + rectangle3.size.height * 1.8)
rectangle5.run(SKAction.sequence([moveDown,removeNode]))
rectangle6.run(SKAction.sequence([moveDown2,removeNode]))
rectangle7.run(SKAction.sequence([moveDown3,removeNode]))
addChild(rectangle1)
addChild(rectangle2)
addChild(rectangle3)
addChild(rectangle5)
addChild(rectangle6)
addChild(rectangle7)
}
有人能帮我找出是什么导致了这种滞后吗?我似乎想不出来。提前谢谢你 动态生成物理实体非常昂贵,这就是为什么每次尝试生成物理实体时,游戏都会出现延迟 我建议您创建对象并将它们放入障碍物阵列中,然后在需要重新创建它们时复制阵列项 你有太多的代码被每个对象重复,我试图通过对每个障碍重用大量代码来减少代码量 仅供参考,SKAction.wait(forDuration:0.0001)与0相同,因此没有意义 你的obstaclesFunc中的代码包含不相关的或者你的问题中没有包含的代码,所以我省略了这个功能,如果它对你的游戏来说是可怕的,你必须找出它并把它放到generateObstacles func中
//variables needed in your scene
private var rectangles = [SKSpriteNode]()
private var moveDown: SKAction!
private var moveDown2: SKAction!
private var moveDown3: SKAction!
private var removeNode: SKAction!
//in your didMove func
//preload the obstacles into an array
createRectangles()
//in your startGame func
//this func call will start the generation of the obstacles
generateObstacles()
func createRectangles() {
let rectangle1 = createRectangle(category: PhysicsNumbering.rectangle_1)
rectangles.append(rectangle1)
let rectangle2 = createRectangle(category: PhysicsNumbering.rectangle_2)
rectangles.append(rectangle2)
let rectangle3 = createRectangle(category: PhysicsNumbering.rectangle_3)
rectangles.append(rectangle3)
let rectangle5 = createRectangle(category: PhysicsNumbering.rectangle_5)
rectangles.append(rectangle5)
let rectangle6 = createRectangle(category: PhysicsNumbering.rectangle_6)
rectangles.append(rectangle6)
let rectangle7 = createRectangle(category: PhysicsNumbering.rectangle_7)
rectangles.append(rectangle7)
let width: CGFloat = rectangle3.size.width
let height: CGFloat = rectangle3.size.height
//position the rectangles afterward creating them since they appear to be relevant to each other
rectangle1.position = CGPoint(x: frame.minX - height * 0.1, y: frame.maxY + width) //use 4.5 for the close one
rectangle2.position = CGPoint(x: frame.minX - width / 40 , y: frame.maxY + height) //use 4.5 for the close one
rectangle3.position = CGPoint(x: frame.midX - width / 1.55, y: frame.maxY + height * 1.8)
rectangle5.position = CGPoint(x: frame.maxX + height * 0.1, y: frame.maxY + width) //use 4.5 for the close one
rectangle6.position = CGPoint(x: frame.maxX + width / 40 , y: frame.maxY + height) //use 4.5 for the close one
rectangle7.position = CGPoint(x: frame.midX + width / 1.55, y: frame.maxY + height * 1.8)
//now create the actions so that they can be used again and again
createActions(height: height / 2)
}
func createActions(height: CGFloat) {
moveDown = SKAction.moveTo(y: frame.minY - height, duration: 2)
moveDown2 = SKAction.moveTo(y: frame.minY - height, duration: 3)
moveDown3 = SKAction.moveTo(y: frame.minY - height, duration: 4)
removeNode = SKAction.removeFromParent()
}
func generateObstacles() {
let randomWaitTime = Int(arc4random_uniform(6) + 1 )
self.run(.wait(forDuration: randomWaitTime) {
loadAndMoveRectangles()
//now call the generate func again to get a diff random time to wait
generateObstacles()
}
}
func loadAndMoveRectangles() {
let rectangle1 = rectangles[0].copy() as? SKSpriteNode
addChild(rectangle1)
let rectangle2 = rectangles[1].copy() as? SKSpriteNode
addChild(rectangle2)
let rectangle3 = rectangles[2].copy() as? SKSpriteNode
addChild(rectangle3)
let rectangle5 = rectangles[3].copy() as? SKSpriteNode
addChild(rectangle5)
let rectangle6 = rectangles[4].copy() as? SKSpriteNode
addChild(rectangle6)
let rectangle7 = rectangles[5].copy() as? SKSpriteNode
addChild(rectangle7)
rectangle1.run(.sequence([moveDown, removeNode]))
rectangle2.run(.sequence([moveDown2, removeNode]))
rectangle3.run(.sequence([moveDown3, removeNode]))
rectangle5.run(.sequence([moveDown, removeNode]))
rectangle6.run(.sequence([moveDown2, removeNode]))
rectangle7.run(.sequence([moveDown3, removeNode]))
}
func createRectangle(category: UInt32) -> SKSpriteNode {
let rectangle = SKSpriteNode(imageNamed: "rectangleWalls")
rectangle.zPosition = 0
rectangle.physicsBody = SKPhysicsBody(texture: rectangleTexture, size: CGSize(width: rectangle1.size.width - 20, height: rectangle1.size.height - 20))
rectangle.physicsBody?.categoryBitMask = category
rectangle.physicsBody?.contactTestBitMask = PhysicsNumbering.player
rectangle.physicsBody?.affectedByGravity = false
rectangle.physicsBody?.isDynamic = true
rectangle.physicsBody?.collisionBitMask = 0
return rectangle
}
我真的不认为轮询变量是正确的方法。您可以使用KVO在值更改时创建通知,这意味着您正在限制操作。我非常确定等待0.00001与等待0.00001不同,但当我有机会时,需要再次检查这一点。0将只在1个更新周期上运行,但0.00001将在2hmmm上运行,这很有趣。我假设,因为最大帧速率可能是每秒0.016次的60fps。因此,任何小于0的值都将等于0。在下一个更新周期之前,它不会应用经过的时间,因此在第一个运行块经过的时间为0,0<0.00001,然后下一次更新,0.016<0.00001为假,因此完成。再次需要确认这个行为。我也会测试一下,如果是这样的话,我会很乐意从答案中删除我的评论。这不会影响我的答案,因为我没有用它来控制时间。不,我会尝试用这个答案来帮助你,但我很难理解OP的发展方向