如何使用 swift 代码让物体在每次触摸屏幕后移动得更快?
How to make object move faster after every touch on screen with swift code?
我在 Xcode 7 BETA 上制作了一个游戏,其中包含一个可以移动并具有许多不同功能的对象。
但问题是物体总是以相同的速度运动,它不会加速或减速。我想要的是让物体在每次触摸屏幕后加速。
我创建了一个名为 "kDefaultXToMovePerSecond" 的常量(请参阅下面的代码),因此使用该常量对象始终以相同的速度移动。
func startMoving() {
let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: 0.7)
runAction(SKAction.repeatActionForever(moveLeft))
}
我把“-”放在常数前面是因为它需要负数才能移动。
我试着让它在每次触摸屏幕后加快速度。我的代码在这里,在 GameScene.swift,
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
if isGameOver {
restart()
} else if !isStarted {
start()
} else {
Dot.flip()
kDefaultXToMovePerSecond + 10
}
}
我的第二个代码示例的这一部分有问题吗?
"kDefaultXToMovePerSecond + 10"
您的代码有两个问题。首先,要获得 kDefaultXToMovePerSecond
更改,必须使用以下语法:kDefaultXToMovePerSecond += 10
,而不是 kDefaultXToMovePerSecond + 10
。我不确定为什么第二种方法(您在代码中使用的方法)没有被编译器捕获,因为它没有将此值分配给任何变量。但是我已经在 playground 中测试了这种语法,并且变量的值不会随着这种语法而改变。其次,虽然您创建了移动精灵的动作,但它永远不会更新,因此精灵的速度永远不会改变。这是因为通过简单地更改 touchesBegan
中的 kDefaultXToMovePerSecond
变量,您只是更改变量本身,而不是未连接到它的 SKAction
中的参数值。有两个选项可以创建您正在寻找的行为。
- 每次调用
touchesBegan
时都会向精灵添加一个新的 SKAction
。此新操作将覆盖之前的操作。
- 删除之前对精灵的操作,然后在每次调用
touchesBegan
时添加一个新的操作。尽管这样做的效果与选项 1 相同,但它的好处是可以释放您创建的 SKActions
。这样可以防止它们堆积起来,永远不会被再次使用,从而占用不必要的内存。
如果您想了解如何完成此操作的指导,请参阅我在 Xcode 7 Beta 模拟器中编写和测试的以下代码。
class GameScene: SKScene {
let player = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 100, height: 50))
var kDefaultXToMovePerSecond: CGFloat = 0
override func didMoveToView(view: SKView) {
player.position = CGPoint(x: 100, y: 200)
addChild(player)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
//Make sure that it is the same kay as below
player.removeActionForKey("anyKeyWillDo")
kDefaultXToMovePerSecond += 10
let moveLeft = SKAction.moveByX(kDefaultXToMovePerSecond, y: 0, duration: 0.7)
player.runAction(SKAction.repeatActionForever(moveLeft), withKey: "anyKeyWillDo")
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
注意:为了实现选项1,去掉player.removeActionForKey("anyKeyWillDo")
这一行。对于选项 2,保留它。
我在 Xcode 7 BETA 上制作了一个游戏,其中包含一个可以移动并具有许多不同功能的对象。
但问题是物体总是以相同的速度运动,它不会加速或减速。我想要的是让物体在每次触摸屏幕后加速。
我创建了一个名为 "kDefaultXToMovePerSecond" 的常量(请参阅下面的代码),因此使用该常量对象始终以相同的速度移动。
func startMoving() {
let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: 0.7)
runAction(SKAction.repeatActionForever(moveLeft))
}
我把“-”放在常数前面是因为它需要负数才能移动。 我试着让它在每次触摸屏幕后加快速度。我的代码在这里,在 GameScene.swift,
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
if isGameOver {
restart()
} else if !isStarted {
start()
} else {
Dot.flip()
kDefaultXToMovePerSecond + 10
}
}
我的第二个代码示例的这一部分有问题吗?
"kDefaultXToMovePerSecond + 10"
您的代码有两个问题。首先,要获得 kDefaultXToMovePerSecond
更改,必须使用以下语法:kDefaultXToMovePerSecond += 10
,而不是 kDefaultXToMovePerSecond + 10
。我不确定为什么第二种方法(您在代码中使用的方法)没有被编译器捕获,因为它没有将此值分配给任何变量。但是我已经在 playground 中测试了这种语法,并且变量的值不会随着这种语法而改变。其次,虽然您创建了移动精灵的动作,但它永远不会更新,因此精灵的速度永远不会改变。这是因为通过简单地更改 touchesBegan
中的 kDefaultXToMovePerSecond
变量,您只是更改变量本身,而不是未连接到它的 SKAction
中的参数值。有两个选项可以创建您正在寻找的行为。
- 每次调用
touchesBegan
时都会向精灵添加一个新的SKAction
。此新操作将覆盖之前的操作。 - 删除之前对精灵的操作,然后在每次调用
touchesBegan
时添加一个新的操作。尽管这样做的效果与选项 1 相同,但它的好处是可以释放您创建的SKActions
。这样可以防止它们堆积起来,永远不会被再次使用,从而占用不必要的内存。
如果您想了解如何完成此操作的指导,请参阅我在 Xcode 7 Beta 模拟器中编写和测试的以下代码。
class GameScene: SKScene {
let player = SKSpriteNode(color: UIColor.redColor(), size: CGSize(width: 100, height: 50))
var kDefaultXToMovePerSecond: CGFloat = 0
override func didMoveToView(view: SKView) {
player.position = CGPoint(x: 100, y: 200)
addChild(player)
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
/* Called when a touch begins */
//Make sure that it is the same kay as below
player.removeActionForKey("anyKeyWillDo")
kDefaultXToMovePerSecond += 10
let moveLeft = SKAction.moveByX(kDefaultXToMovePerSecond, y: 0, duration: 0.7)
player.runAction(SKAction.repeatActionForever(moveLeft), withKey: "anyKeyWillDo")
}
override func update(currentTime: CFTimeInterval) {
/* Called before each frame is rendered */
}
}
注意:为了实现选项1,去掉player.removeActionForKey("anyKeyWillDo")
这一行。对于选项 2,保留它。