摘要 最近在实践swift语言,想把swift中的snake and ladder示例程序写成一个真正的小游戏,本日志是我遇到的一个问题和无奈的解决方法。swift UIButton SpriteKit UIKit 圆角矩形按钮
我对objective-C不是很熟,UIKit以前没有用过,SpriteKit也只看了遍教程,然后看了一遍swift语言教程,此时开始编写这个程序,所以遇到的问题比较小儿科,解决方法也是曲线救国,希望有高人指点解决这些问题的简单方法,有好的解决方法后,我会随时进行本日志的修改,以免误导他人。
程序界面很是简单
然后点击中间的游戏区域,会roll色子,随机产生1~6的数字,飞机前进若干步,遇到梯子向前跳若干步,而遇到蛇则后退若干步,指导抵达25格,游戏结束。
上面有一个标签,显示游戏状态和Roll点值。
下面有一个RESTART按钮,用来重新开始游戏,本日志的关键就是这个按钮。
起先我想法很简单,就是在sprite的scene里边添加一个按钮,但是SpriteKit里边我并没有发现类似按钮控件什么的,开始我使用Label替代按钮的功能,就是在点击事件中判断控件,然后再执行按钮相关代码,这种方法一是按钮太丑,二是点击时没有按钮的动作,三是按钮的方法调用实在是太山寨了。
后来我发现了UIButton,我参考了下面添加按钮的Objective-C代码:
CGRect frame = CGRectMake(90, 200, 200, 60); UIButton *someAddButton = [UIButton buttonWithType:UIButtonTypeRoundedRect]; someAddButton.backgroundColor = [UIColor clearColor]; [someAddButton setTitle:@"动态添加一个按钮!" forState:UIControlStateNormal]; someAddButton.frame = frame; [someAddButton addTarget:self action:@selector(someButtonClicked) forControlEvents:UIControlEventTouchUpInside]; [self.view addSubview:someAddButton];
在此首先得看苹果一个官方文档,Using Swift with Cocoa and Objective-C
怎样修改OC代码到swift,按理上述代码和说明,第二行理应该改为
var someAddButton = UIButton.buttonWithType(.RoundedRect) as UIButton
其中按住command键单击buttonWithType函数,可以看出这是一个类型函数,并且返回AnyObject!类型,所以使用了as,但是并不能如我所愿,因为UIButtonType没有圆角矩形这个枚举类型
?
1
2
3
4
5
6
7
8
9
enum
UIButtonType : Int {
case
Custom
case
System
case
DetailDisclosure
case
InfoLight
case
InfoDark
case
ContactAdd
}
那我先放弃这个圆角矩形,使用一个普通按钮吧
?
1
2
3
4
5
6
7
var btn = UIButton()
btn.setTitle(
"RESTART"
,forState: .Normal)
btn.frame = CGRect(x:screen.bounds.size.width/2-50, y:screen.bounds.size.height-100,width:100,height:50)
self.addChild(btn)
问题又出现了,btn根本不是一个SKNode,无法添加上去,看OC的示例,明显btn是添加在view上的,于是改为注释的那一句,但是运行后,并没有显示按钮。这可如何是好呀。
于是我又开始查找资料,终于我发现了苹果另一个代码示例文档:UICatalog: Creating and Customizing UIKit Controls in Swift,这个示例代码我下载后,并没能运行,但是其中的各种控件使用示例肯定是不会错的,UIButton是添加在ViewController里边的,我的工程中就3个swift文件,其中一个就是GameViewController.swift,我看到里边的代码后就明白了,GameScene都是添加到这里边显示的,所以按钮也应该是添加到这儿。
所以在GameViewController的viewDidLoad方法中写添加按钮的代码:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
var btn:UIButton = UIButton()
var gameScene:GameScene?
override func viewDidLoad() {
super.viewDidLoad()
if
let scene = GameScene.unarchiveFromFile(
"GameScene"
) as? GameScene {
let skView = self.view as SKView
skView.showsFPS =
true
skView.showsNodeCount =
true
skView.ignoresSiblingOrder =
true
scene.scaleMode = .AspectFill
skView.presentScene(scene)
var screen = UIScreen.mainScreen()
println(
"screen width:\(screen.bounds.size.width),height:\(screen.bounds.size.height)"
)
btn.setTitle(
"RESTART"
,forState: .Normal)
btn.backgroundColor = UIColor.redColor()
btn.frame = CGRect(x:screen.bounds.size.width/2-50, y:screen.bounds.size.height-100,width:100,height:50)
skView.addSubview(btn)
gameScene = scene
}
}
这样添加后,按钮总算是出来了,但还是无比的难看,我试过那个按钮类型,没有一个是能用的。
一是没有圆角矩形,二是一点没有按钮那种凸起感觉。
我又看了几个UIButton的几个方法,发现可以同时设置背景图片和设置按钮文字,那我不就可以弄一个按钮的图片,来制作一个圆角矩形的按钮了么。
于是我制作了下面的按钮图片:
需要注意:这个图片最好是png格式,这个橙色区域就是图片的全部,并没有白色底背景。我是使用苹果自带的图片预览的智能套索剪切的。
然后使用如下代码即可生成本日志开始截图的按钮:
?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
class
GameViewController: UIViewController {
var btn:UIButton = UIButton()
var gameScene:GameScene?
override func viewDidLoad() {
super.viewDidLoad()
if
let scene = GameScene.unarchiveFromFile(
"GameScene"
) as? GameScene {
let skView = self.view as SKView
skView.showsFPS =
true
skView.showsNodeCount =
true
skView.ignoresSiblingOrder =
true
scene.scaleMode = .AspectFill
skView.presentScene(scene)
var screen = UIScreen.mainScreen()
println(
"screen width:\(screen.bounds.size.width),height:\(screen.bounds.size.height)"
)
let buttonTitle = NSLocalizedString(
"RESTART"
, comment:
"you will restart the game"
)
btn.setTitle(buttonTitle,forState: .Normal)
var image = UIImage(named:
"button"
)
btn.setBackgroundImage(image,forState: .Normal)
btn.frame = CGRect(x:screen.bounds.size.width/2-50, y:screen.bounds.size.height-100,width:100,height:50)
btn.addTarget(self, action:
"buttonClicked:"
, forControlEvents: .TouchUpInside)
skView.addSubview(btn)
gameScene = scene
}
}
func buttonClicked(sender: UIButton) {
print(
"A button was clicked: \(sender)."
)
if
let scene = gameScene? {
println(
"board width:\(scene.spriteBoard.size.width),height:\(scene.spriteBoard.size.height)"
)
var alert = scene.gameRestartAsk()
presentViewController(alert, animated:
true
, completion: nil)
}
}
}
本人曾用过Label的方法,需要判断位置再加调用方法,比较麻烦而且效果也不好,也曾经把Scene拉小一点把button放在view上感觉还可以不过总是有隔了一层调用的感觉,所以发现这个解决方法后就马上转载一下了。