Swift - SpriteKit 如何用精灵制作按钮
前言????前段时间,在知乎看到一个回答,iOS开发以及被玩的差不多了,只有SpriteKit,SceneKit这两个难兄难弟还没有被“开发”。确实,毕竟做手游,有unity,虚幻等,谁用这玩意。。 预览按钮可以设置不同的点击颜色,和文字颜色,但是暂不支持图片。 讲解先上代码 // // MeCustomButton.swift // mng // // Created by WTFKL on 2018/4/16. // Copyright ? 2018年 WTF. All rights reserved. // import SpriteKit import UIKit class MeCustomButton: SKSpriteNode{ /** 在创建完成后,调用touchUpInside方法来触发点击事件 */ private var m_ButtonLabel : SKLabelNode?; private var border : SKShapeNode?; //边框颜色 public var borderColor : SKColor = SKColor.yellow{ didSet{ border?.strokeColor = borderColor; } }; //按钮背景颜色 public var m_BackgroundColor : SKColor = SKColor.white{ didSet{ border?.fillColor = m_BackgroundColor; } }; //按钮文字 public var m_LabelText : String = "Label"{ didSet{ m_ButtonLabel?.text = m_LabelText; } }; //按钮字体颜色 public var m_fontColor : SKColor = .black{ didSet{ m_ButtonLabel?.fontColor = m_fontColor; } }; //按钮边框宽度 public var m_borderLineWidth:CGFloat = 1{ didSet{ border?.lineWidth = m_borderLineWidth; } } //按钮文字字体 public var m_FontName : String = ""{ didSet{ m_ButtonLabel?.fontName = m_FontName; } } //按钮文字尺寸 public var m_FontSize : CGFloat = 20 { didSet{ m_ButtonLabel?.fontSize = m_FontSize; } } public var clickEvent = {}; convenience init(btnName : String,btnSize:CGSize,btnCornerRadius:CGFloat) { self.init(color: .clear,size: btnSize); self.color = .clear; self.name = btnName; let location = CGRect(x: -self.frame.size.width/2,y:-self.frame.size.height/2,width: self.frame.size.width,height: self.frame.size.height); border = SKShapeNode(rect: location,cornerRadius: btnCornerRadius); border!.fillColor = m_BackgroundColor; border?.lineWidth = m_borderLineWidth; border?.strokeColor = borderColor; self.addChild(border!); m_ButtonLabel = SKLabelNode(text: m_LabelText); m_ButtonLabel?.position = CGPoint(x: 0,y: -((m_ButtonLabel?.frame.size.height)!/2)); m_ButtonLabel?.fontColor = m_fontColor; m_ButtonLabel?.fontName = m_FontName; m_ButtonLabel?.fontSize = m_FontSize; self.addChild(m_ButtonLabel!); } public func touchUpInside(highLightBGColor:SKColor,highLightFontColor:SKColor){ let oldBGColor = self.m_BackgroundColor; let oldFontColor = self.m_fontColor; self.m_BackgroundColor = highLightBGColor; self.m_fontColor = highLightFontColor; let waitTime = SKAction.wait(forDuration: 0.05); let bgcolor = SKAction.run { self.m_BackgroundColor = oldBGColor; self.m_fontColor = oldFontColor; } self.run(SKAction.sequence([waitTime,bgcolor])); clickEvent(); } } 首先是属性private var m_ButtonLabel : SKLabelNode?; private var border : SKShapeNode?; //边框颜色 public var borderColor : SKColor = SKColor.yellow{ didSet{ border?.strokeColor = borderColor; } }; //按钮背景颜色 public var m_BackgroundColor : SKColor = SKColor.white{ didSet{ border?.fillColor = m_BackgroundColor; } }; //按钮文字 public var m_LabelText : String = "Label"{ didSet{ m_ButtonLabel?.text = m_LabelText; } }; //按钮字体颜色 public var m_fontColor : SKColor = .black{ didSet{ m_ButtonLabel?.fontColor = m_fontColor; } }; //按钮边框宽度 public var m_borderLineWidth:CGFloat = 1{ didSet{ border?.lineWidth = m_borderLineWidth; } } //按钮文字字体 public var m_FontName : String = ""{ didSet{ m_ButtonLabel?.fontName = m_FontName; } } //按钮文字尺寸 public var m_FontSize : CGFloat = 20 { didSet{ m_ButtonLabel?.fontSize = m_FontSize; } } public var clickEvent = {};//点击事件 一目了然,重写了set方法,因为后面要随时更改这些属性。swift重写set方法也是比较奇葩的。重点提一下 public var clickEvent = {} 这个传递了一个闭包,将点击事件传递进来,方便调用。 其次是便利构造方法convenience init(btnName : String,cornerRadius: btnCornerRadius);//设置圆角 border!.fillColor = m_BackgroundColor;//填充色 border?.lineWidth = m_borderLineWidth;//边框宽度 border?.strokeColor = borderColor;//边框颜色 self.addChild(border!); m_ButtonLabel = SKLabelNode(text: m_LabelText);//添加文字label m_ButtonLabel?.position = CGPoint(x: 0,y: -((m_ButtonLabel?.frame.size.height)!/2));//尺寸 m_ButtonLabel?.fontColor = m_fontColor;//字体颜色 m_ButtonLabel?.fontName = m_FontName;//字体 m_ButtonLabel?.fontSize = m_FontSize;//字体尺寸 self.addChild(m_ButtonLabel!); } 便利构造方法常规写法,附上默认数值属性。 再者就是点击事件方法public func touchUpInside(highLightBGColor:SKColor,highLightFontColor:SKColor){//传入高亮背景色,高亮文字颜色 let oldBGColor = self.m_BackgroundColor;//保存原本的颜色 let oldFontColor = self.m_fontColor;//保存原本的文字颜色 self.m_BackgroundColor = highLightBGColor;//把传入的高亮颜色赋值 self.m_fontColor = highLightFontColor;//把传入的高亮颜色赋值 let waitTime = SKAction.wait(forDuration: 0.05);//按钮等待时间 let bgcolor = SKAction.run {//动画 self.m_BackgroundColor = oldBGColor; self.m_fontColor = oldFontColor; } self.run(SKAction.sequence([waitTime,bgcolor]));//运行动画 clickEvent();//调用闭包点击事件 } 这里就必须重点提一下了。因为按钮点击最好是有反馈。所以,运用SKSpritekit的动画特性,用SKAction的wait,来等待0.5s,来模拟按钮反馈。这是最关键的。 CustomButton类就完成了如何使用这个类?//便利构造方法,初始化出一个100*50的button,带弧度为5的边框 startButton = MeCustomButton(btnName: "start",btnSize:CGSize(width: 100,height: 50),btnCornerRadius: 5); startButton?.position = CGPoint(x: 0,y: 5);//button的位置 startButton?.m_fontColor = .white;//文字颜色默认为白色 startButton?.m_BackgroundColor = .clear;//背景色为透明 startButton?.m_FontName = "GB18030Bitmap";//设置字体,然而手机没这个字体,可以忽略 startButton?.m_LabelText = "开始";//设置文字 startButton?.m_FontSize = 35;//设置文字尺寸 startButton?.borderColor = .white;//设置文字颜色 startButton?.m_borderLineWidth = 1;//边框宽度 startButton?.clickEvent = {//设置点击事件 let firstScene = SKScene(fileNamed: "Third")!//这里我点击跳转第三个场景 self.view?.presentScene(firstScene,transition: SKTransition.crossFade(withDuration: 0.5)); }; self.addChild(startButton!);//场景添加按钮 常规设置属性,点击事件也一目了然,不多说。 注意override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) { for t in touches { let location = t.location(in: self); let mnode = nodes(at: location); for nnode in mnode{ let na = nnode as? MeCustomButton; if(na?.name == "instructions"){ instructions?.touchUpInside(highLightBGColor: .white,highLightFontColor: .black); }else if(na?.name == "start"){ startButton?.touchUpInside(highLightBGColor: .white,highLightFontColor: .black); } } } } 与通常button不同的是,我们必须通过触摸事件来判断,你点的是哪个精灵。touchesBegan用法和常规也一样,找出你的精灵后,调用touchUpInside方法,传入你想要的高亮颜色。这时候,你的button就算是完成了。 总结????怎么样,造轮子也挺不错的。我个人觉得还是没有完全把这个方法抽好,还是很麻烦。而且不支持图片,等过段时间有空了,把这个方法在完善一下,支持图片,方法命名什么的都根据UIButton来。各位看官,也试试看吧,喜欢给个赞哦。有问题请小心翼翼指出,心理承受能力弱,哈哈。预告一下,之后几天,会写一篇完整的swift游戏开发文章。 (编辑:李大同) 【声明】本站内容均来自网络,其相关言论仅代表作者个人观点,不代表本站立场。若无意侵犯到您的权利,请及时与联系站长删除相关内容! |