我的 SKSpriteNode 速度值未正确更新
Posted
技术标签:
【中文标题】我的 SKSpriteNode 速度值未正确更新【英文标题】:My SKSpriteNode speed values are not updating properly 【发布时间】:2020-10-19 22:46:19 【问题描述】:我想要做的是更新我的 SKSpriteNodes,这样我就可以动态地改变它们的滚动速度,但是它们并不能真正持续地工作。我没有包含代码,但是我有另一种带有开关盒的方法,该方法在状态更改时设置platformSpeed
的值(在这种情况下,开关盒使用 UIButtons 更改)。在我的代码中,我有一个 SKSpriteNode
数组和一个包含 didSet
的 platformSpeed
属性,因此我的值已正确更新。
在创建平台的方法中,我将 SpriteNode 分组到 platformGroup
中,然后使用 addChild()
循环遍历它们。不知道它为什么会这样,但这里有一个快速视频,展示了它的实际效果:
demonstration clip
因此,我正在使用按钮更改开关盒,如您所见,并非所有节点的速度都在正确更新,有些节点比其他节点更快并最终通过它们。我需要他们彼此保持相等的距离。
现在这是我的代码:
class GameScene: SKScene, SKPhysicsContactDelegate
var platformGroup = [SKSpriteNode]()
var platformSpeed: CGFloat = 1.0
didSet
for platforms in platformGroup
platforms.speed = platformSpeed
let platformTexture = SKTexture(imageNamed: "platform")
var platformPhysics: SKPhysicsBody!
func createPlatforms()
let platformLeft = SKSpriteNode(texture: platformTexture)
platformLeft.physicsBody = platformPhysics.copy() as? SKPhysicsBody
platformLeft.physicsBody?.isDynamic = false
platformLeft.scale(to: CGSize(width: platformLeft.size.width * 4, height: platformLeft.size.height * 4))
platformLeft.zPosition = 20
let platformRight = SKSpriteNode(texture: platformTexture)
platformRight.physicsBody = platformPhysics.copy() as? SKPhysicsBody
platformRight.physicsBody?.isDynamic = false
platformRight.scale(to: CGSize(width: platformRight.size.width * 4, height: platformRight.size.height * 4))
platformRight.zPosition = 20
let scoreNode = SKSpriteNode(color: UIColor.clear, size: CGSize(width: frame.width, height: 32))
scoreNode.physicsBody = SKPhysicsBody(rectangleOf: scoreNode.size)
scoreNode.physicsBody?.isDynamic = false
scoreNode.name = "scoreDetect"
scoreNode.zPosition = 40
platformGroup = [platformLeft, platformRight, scoreNode]
let yPosition = frame.width - platformRight.frame.width
let max = CGFloat(frame.width / 4)
let xPosition = CGFloat.random(in: -80...max)
let gapSize: CGFloat = -50
platformLeft.position = CGPoint(x: xPosition + platformLeft.size.width - gapSize, y: -yPosition)
platformRight.position = CGPoint(x: xPosition + gapSize, y: -yPosition)
scoreNode.position = CGPoint(x: frame.midX, y: yPosition - (scoreNode.size.width / 1.5))
let endPosition = frame.maxY + (platformLeft.frame.height * 3)
let moveAction = SKAction.moveBy(x: 0, y: endPosition, duration: 7)
let moveSequence = SKAction.sequence([moveAction, SKAction.removeFromParent()])
for platforms in platformGroup
addChild(platforms)
platforms.run(moveSequence)
platformCount += 1
func loopPlatforms()
let create = SKAction.run [unowned self] in
self.createPlatforms()
platformCount += 1
let wait = SKAction.wait(forDuration: 1.1)
let sequence = SKAction.sequence([create, wait])
let repeatForever = SKAction.repeatForever(sequence)
run(repeatForever)
【问题讨论】:
【参考方案1】:我想我知道出了什么问题。当您更改platformSpeed
时,它会更改platformGroup
中所有平台的速度。并且createPlatforms()
被多次调用。现在,每次调用它时,您都会创建一对平台并将它们分配给platformGroup
。由于您多次调用该函数,它会覆盖数组中的任何现有值。这就是为什么更改 platformSpeed
只会更新您创建的最新平台的速度——旧平台保持相同的速度,因为它们不再在 platformGroup
中。
要解决此问题,我的建议是让 platformGroup 存储当前屏幕上的所有平台。你可以通过改变来做到这一点
platformGroup = [platformLeft, platformRight, scoreNode]
类似
let newNodes = [platformLeft, platformRight, scoreNode]
platformGroup += newNodes
// Alternatively, platformGroup.append(contentsOf: newNodes)
现在您需要确保 1) 仅将新节点添加到场景中,以及 2) 从父节点中删除旧节点时从 platformGroup
中删除它们。你可以通过改变来做到这一点
let moveAction = SKAction.moveBy(x: 0, y: endPosition, duration: 7)
let moveSequence = SKAction.sequence([moveAction, SKAction.removeFromParent()])
for platforms in platformGroup
addChild(platforms)
platforms.run(moveSequence)
类似
let moveAction = SKAction.moveBy(x: 0, y: endPosition, duration: 7)
for node in newNodes
let moveSequence = SKAction.sequence([
moveAction,
SKAction.removeFromParent(),
SKAction.run
self.platformGroup.remove(node)
])
addChild(node)
node.run(moveSequence)
既然您正在跟踪所有平台,那么您的速度更改应该一致地应用于屏幕上的每个平台。希望这行得通!
【讨论】:
以上是关于我的 SKSpriteNode 速度值未正确更新的主要内容,如果未能解决你的问题,请参考以下文章
如何找到 SKSpriteNode 的速度作为 x 和 y 值?