在我的游戏中,有一个类似于向左移动的“墙”。我想根据我添加到i
方法的计数touchesBegan
更改速度:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent {
count++
}
func startMoving() {
let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: 1 )
let move = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: 0.5)
if(count <= 10)
{
runAction(SKAction.repeatActionForever(moveLeft))
}
else
{
runAction(SKAction.repeatActionForever(move))
}
}
但它不起作用。你能帮忙吗?
答案 0 :(得分:1)
正如我所说,有很多变化需要做:
首先让我们改变MLWall类并添加一个将在startMoving方法中使用的持续时间属性:
var duration:NSTimeInterval = 0.5
然后仍在MLWall类中更改init方法:
init(duration: NSTimeInterval) {
self.duration = duration
//...
}
并更改startMoving方法以使用此传递的参数:
func startMoving() {
let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: self.duration)
runAction(SKAction.repeatActionForever(moveLeft))
}
这些是Wall类内部的变化。现在让我们在WallGenerator类中进行一些更改:
第一个WallGenerator类应该知道墙应该有多快。所以我们正在添加属性来存储该信息:
var currentDuration: NSTimeInterval = 1 // I named it duration, because SKAction takes duration as a parameter, but this actually affects on speed of a wall.
之后,必须更改的第一个方法是startGeneratingWallsEvery(second :) into startGeneratingWallsEvery(second:duration:
//duration parameter added
func startGeneratingWallsEvery(seconds: NSTimeInterval, duration : NSTimeInterval) {
self.currentDuration = duration
generationTimer = NSTimer.scheduledTimerWithTimeInterval(seconds, target: self, selector: "generateWall", userInfo: nil, repeats: true)
}
在这里,我们正在让WallGenerator了解所需的墙速度。 并且为了使用该速度而必须改变的下一个方法是:
//duration parameter added
func generateWall() {
//...
//Duration parameter added
let wall = MLWall(duration: self.currentDuration)
//...
}
还有一个GameScene。在那里,我添加了tapCounter属性:
let debugLabel = SKLabelNode(fontNamed: "Arial") //I've also added a debug label to track taps count visually
var tapCounter = 0
如果您想查看点击次数,可以使用以下方法初始化标签:
//Setup debug label
debugLabel.text = "Tap counter : \(tapCounter)"
debugLabel.position = CGPoint(x: CGRectGetMidX(frame), y: CGRectGetMaxY(frame)-50.0)
debugLabel.fontColor = SKColor.purpleColor()
self.addChild(debugLabel)
首先我改变了开始方法:
func start() {
//...
// adding duration parameter in method call
wallGenerator.startGeneratingWallsEvery(1,duration: 1)
}
重要的部分是:wallGenerator.startGeneratingWallsEvery(1,duration: 1)
表示每秒开始生成墙,持续时间为一秒(这会影响节点的速度)。
接下来,我已将场景中的touchesBegan修改为:
if isGameOver {
restart()
} else if !isStarted {
start()
} else {
tapCounter++
debugLabel.text = "Tap counter : \(tapCounter)"
if(tapCounter > 10){
wallGenerator.stopGenerating()
wallGenerator.startGeneratingWallsEvery(0.5, duration:0.5)
}
hero.flip()
}
然后,更改了restart()方法,以便在游戏结束时重新启动计数器:
func restart() {
tapCounter = 0
//...
}
这就是它。我想我没有忘记一些东西,但在我身边,它可以正常工作。另请注意,使用此GitHub project中的NSTimer并不是您想要的SpriteKit。这是因为NSTimer不尊重场景,观看或节点的暂停状态。这意味着即使你认为游戏暂停,它也会继续产卵。 SKAction将是这种情况的首选替代品。
希望这会有所帮助,如果您有其他问题,请随时提出,但我想您可以从上面的代码中了解发生了什么。基本上所做的是WallGenerator已经意识到他们的墙节点应该有多快,并且Wall节点已经意识到它应该有多快......
修改强>
还有另一种通过使用键运行移动动作来改变墙壁速度的方法。然后,在产生的那一刻,根据tapCounter值,您可以通过键访问移动动作,并直接更改动作的速度属性......这可能是一种较短的方式,但仍需要一些更改(通过Wall类中的duration参数和在场景中实现tapCounter)。
答案 1 :(得分:0)
尝试这样做:
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent {
count++
startMoving()
}
func startMoving() {
removeAllActions()
let moveLeft = SKAction.moveByX(-kDefaultXToMovePerSecond, y: 0, duration: count <= 10 ? 1.0 : 0.5)
runAction(SKAction.repeatActionForever(moveLeft))
}
击> <击> 撞击>
当我阅读你的问题下面的评论时,你提出了一个非常不清楚的问题,但是你的代码中仍存在思想问题。
如果我理解了所有内容,您的touchesBegan
方法就会在墙上实施,因此它对新生成的墙没有任何影响。您必须将该逻辑移动到场景中,然后以速度作为参数生成新墙,或者至少使count
成为类var,因此每个墙都可以访问它,但您仍需要处理场景,因为现在触摸是在用户直接在墙上点击时处理的。