
为了测试的需要,我们来实现一个游戏中的Restart(重置)按钮,点击该按钮,游戏中所有敌人都会重新向你袭来,场景也会发生重置。
首先我们需要在游戏中创建一个初始化方法initGame,我们将原来在didMove方法中的部分代码移至该方法中:
func initGame(){ // 初始化游戏场景及敌人 }
那么原来的didMove方法就简化为:
override func didMove(to view: SKView) { // 初始化固定游戏场景,包括物理引擎 initGame() }
我们希望按钮外围有一个边框,这样看起来更像一个按钮,所以总共需要两个SKNode来模拟:一个label加一个shapeNode:
var restart:SKLabelNode! var border:SKShapeNode!
在刚才的didMove方法中加入初始化restart和border的代码:
restart = SKLabelNode(fontNamed: "Chalkduster") restart.text = "Restart" restart.position = CGPoint(x: frame.size.width - 16 - restart.frame.size.width, y: 16) restart.horizontalAlignmentMode = .right addChild(restart) restart.fontColor = .red border = SKShapeNode(rect: restart.frame CGFloat(5), cornerRadius: 10.0) border.lineWidth = 5.0 border.strokeColor = .yellow addChild(border)
为了更好地处理按钮外部的边框的大小及位置,我特地写了一个 操作符,来根据现有label的frame返回一个包裹边框的CGRect:
func (left:CGRect,right:CGFloat)->CGRect{ return CGRect(x: left.origin.x - right, y: left.origin.y - right, width: left.size.width right, height: left.size.height right) }
现在运行App可以看到一个类似按钮的Node出现在屏幕右下角,但是我们触摸它的时候没有任何反应,因为我们还没有做出反馈哦 ;)

在touchesBegan方法中加入如下代码:
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) { guard let touch = touches.first else {return} let location = touch.location(in: self) if nodes(at: location).contains(restart){ //在这里我们等会尝试做一些动画效果... if gameOver { initGame() } } }
我们可以看到,当玩家触摸restart按钮时,我们判断游戏是否已经结束,如果是我们重新开始游戏,这就是之前创建initGame发放的意义啊!

现在运行App,在游戏结束时触摸restart按钮时,游戏重新开始了!所以restart按钮的功能已经实现了.但是…它只是看起来像一个按钮,但按下时完全没有视觉反馈,让人很无语,处女座的你们能忍吗(本猫不是处女座都不能忍啊!)

所以让我们利用SpriteKit提供的Action来完成这个视觉鸡肋吧 ;)
我们想要的效果是当玩家按下restart按钮,其边框会发生大小变化并向”下”发生稍许位移,同时border内部增加填充色.restart按钮本身也要有所表现啊!我们会改变文字颜色和文字大小.当然所有这些改变在一个很小的时间间隔后会恢复为原来的状态.
在上面的 “//在这里我们等会尝试做一些动画效果…” 注释位置添加如下代码:
border.fillColor = .red let mov = SKAction.moveBy(x: -3, y: -3, duration: 0.1) let scale = SKAction.scale(to: 1.02, duration: 0.1) let grp = SKAction.group([mov,scale]) let act = SKAction.wait(forDuration: 0.1) let blk = SKAction.run {[unowned self] in self.border.fillColor = .clear self.border.position = CGPoint(x:self.border.position.x 3,y:self.border.position.y 3) self.border.setScale(1.0) } border.run(SKAction.sequence([grp,act,blk])) restart.fontColor = .yellow restart.fontSize -= 5 let btnBlk = SKAction.run {[unowned self] in self.restart.fontColor = .red self.restart.fontSize = 5 } restart.run(SKAction.sequence([act,btnBlk]))
代码的含义上面已经解释过了,我们允许App来看一下实际的效果吧:

好了,无论上一次我们被障碍物砸的有多惨,我们都可以轻轻点击Restart按钮重新开始了,这对于快速测试来说简直是棒棒哒哦!!!你值得拥有 :)




















