我是swift的新手,并拥有一个我创造了游戏的SKScene。我似乎无法弄清楚如何构建菜单。如果看到两个解决方案创建另一个视图控制器或另一个SKScene,但它们都非常混乱和复杂。我愿意使用这些方法或任何其他方法,有没有人有任何技巧来解决这个问题。一些代码会有所帮助。谢谢你的帮助。
答案 0 :(得分:2)
有很多方法可以在 Sprite-Kit 中获取菜单。
通常人们会绘制一些SKLabelNode
或SKSpriteNode
来构建菜单语音或制作构建此类结构的特定SKNode
。
但我想对StackView
的评论提出建议。
我们知道StackView
是一个UIKit
元素:
提供简化的界面,用于布置视图集合 在一列或一行中。
因此,我们可以构建一个包含所有菜单语音的垂直StackView
(PS下面的代码显示了一个简单的标签集合,您可以根据需要自定义StackView
个视图):
import SpriteKit
import UIKit
protocol StackViewDelegate: class {
func didTapOnView(at index: Int)
}
class GameMenuView: UIStackView {
weak var delegate: StackViewDelegate?
override init(frame: CGRect) {
super.init(frame: frame)
self.axis = .vertical
self.distribution = .fillEqually
self.alignment = .fill
self.spacing = 5
self.isUserInteractionEnabled = true
//set up a label
for i in 1...5 {
let label = UILabel()
label.text = "Menu voice \(i)"
label.textColor = UIColor.white
label.backgroundColor = UIColor.blue
label.textAlignment = .center
label.tag = i
self.addArrangedSubview(label)
}
configureTapGestures()
}
required init(coder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
private func configureTapGestures() {
arrangedSubviews.forEach { view in
view.isUserInteractionEnabled = true
let tapGesture = UITapGestureRecognizer(target: self, action: #selector(didTapOnView))
view.addGestureRecognizer(tapGesture)
}
}
func didTapOnView(_ gestureRecognizer: UIGestureRecognizer) {
if let index = arrangedSubviews.index(of: gestureRecognizer.view!) {
delegate?.didTapOnView(at: index)
}
}
}
class GameScene: SKScene, StackViewDelegate {
var gameMenuView = GameMenuView()
private var label : SKLabelNode?
override func didMove(to view: SKView) {
self.label = self.childNode(withName: "//helloLabel") as? SKLabelNode
if let label = self.label {
label.alpha = 0.0
label.run(SKAction.fadeIn(withDuration: 2.0))
}
// Menu setup with stackView
gameMenuView.frame=CGRect(x:20,y:50,width:280,height:200)
view.addSubview(gameMenuView)
gameMenuView.delegate = self
}
func didTapOnView(at index: Int) {
switch index {
case 0: print("tapped voice 1")
case 1: print("tapped voice 2")
case 2: print("tapped voice 3")
case 3: print("tapped voice 4")
case 4: print("tapped voice 5")
default:break
}
}
}
<强>输出强>:
答案 1 :(得分:1)
下面提到的代码使用class ViewController: UIViewController {
private let baseSection = UIStackView()
private let section1 = UIStackView()
private let titleLabel = UILabel()
private let button1 = UIButton(type: .custom)
private let button2 = UIButton(type: .custom)
private let button3 = UIButton(type: .custom)
//MARK: Load view
override func viewDidLoad() {
super.viewDidLoad()
setupViews()
}
//MARK: Setup views
private func setupViews() {
setupBaseSection()
setupTitleLabel()
setupButton1()
setupSection1()
setupButton2()
setupButton3()
}
private func setupTitleLabel() {
titleLabel.text = "Swirl"
titleLabel.font = UIFont.preferredFont(forTextStyle: .headline)
titleLabel.textColor = #colorLiteral(red: 0.8156862745, green: 0.9137254902, blue: 0.1647058824, alpha: 1)
baseSection.addArrangedSubview(titleLabel)
}
private func setupButton1() {
button1.backgroundColor = #colorLiteral(red: 0.9098039216, green: 0.168627451, blue: 0.3921568627, alpha: 1)
baseSection.addArrangedSubview(button1)
button1.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.2).isActive = true
button1.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
private func setupButton2() {
button2.backgroundColor = #colorLiteral(red: 0.8156862745, green: 0.9137254902, blue: 0.1647058824, alpha: 1)
section1.addArrangedSubview(button2)
button2.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.1).isActive = true
button2.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
private func setupButton3() {
button3.backgroundColor = #colorLiteral(red: 0.8156862745, green: 0.9137254902, blue: 0.1647058824, alpha: 1)
section1.addArrangedSubview(button3)
button3.widthAnchor.constraint(equalTo: view.widthAnchor, multiplier: 0.2).isActive = true
button3.heightAnchor.constraint(equalToConstant: 50).isActive = true
}
//MARKL Set up stack views
private func setupBaseSection() {
baseSection.axis = .vertical
baseSection.distribution = .fill
baseSection.alignment = .center
baseSection.spacing = 10
baseSection.translatesAutoresizingMaskIntoConstraints = false
view.addSubview(baseSection)
baseSection.leadingAnchor.constraint(equalTo: view.leadingAnchor).isActive = true
baseSection.trailingAnchor.constraint(equalTo: view.trailingAnchor).isActive = true
baseSection.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
}
private func setupSection1() {
section1.axis = .horizontal
section1.distribution = .equalSpacing
section1.alignment = .fill
section1.spacing = 20
baseSection.addArrangedSubview(section1)
}
}
创建了2个部分。
你可以使用类似的方法。
# this line only works in python2
self.output_template = base64.b64encode(output_template).decode("ascii")
# You must convert str to bytes in Python3
self.output_template = base64.b64encode(output_template.encode("ascii")).decode("ascii")
答案 2 :(得分:0)
我经历过将UIButtons和UILabels添加到SpriteKit场景可以非常技术性地解决它们的定位问题。由于UI对象位于视图上而不是直接位于SpriteKit场景上。您可以将SKSpriteNode用作Button,将SKLabelNode用作Title,用于菜单场景。
Sprite工具包场景放置在UIView上,并根据您定义的缩放模式进行缩放。苹果默认比例模式.aspectFill无需调整定位于不同手机设备屏幕尺寸的Sprite工具包对象。
这是SKSpriteNode的自定义类,具有与按钮相同的功能。
import Foundation
import SpriteKit
class ButtonLabelNode : SKSpriteNode {
let buttonPressed: () -> ()
init(texture: SKTexture?, color: UIColor, size: CGSize, text: String, buttonPressed: @escaping () -> ()) {
self.buttonPressed = buttonPressed
super.init(texture: texture, color: color, size: size)
let label = SKLabelNode(fontNamed: "Futura")
label.fontSize = 50
label.fontColor = SKColor.red
label.position = CGPoint.init(x: 0.0, y: 0.0)
label.zPosition = 1
label.verticalAlignmentMode = .center
label.text = text
self.addChild(label)
self.isUserInteractionEnabled = true
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
self.alpha = 0.8
}
override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
self.alpha = 1.0
buttonPressed()
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
当SpriteNode上的触摸开始时,当触摸结束时,alpha减小到0.8并返回到1.0,给它带来与UIButton相同的视觉效果。在重写的函数'touchesEnded'中,每次按下按钮时都会调用一个函数,该函数在初始化程序中添加,可以在游戏场景中初始化。
override func didMove(to view: SKView) {
let labelNode = LabelNode(texture: nil, color: .white, size: CGSize.init(width: 200, height: 100), text: "Play", buttonPressed: playButton)
labelNode.position = CGPoint(x: self.frame.midX, y: self.frame.midY)
self.addChild(labelNode)
}
func playButton()
{
print("play")
}
您可以根据需要创建此类的任意数量的实例,为其提供自己的功能,因为添加的初始化函数对于其自己的实例是唯一的。与类的必需协议方法不同,因为它会影响类的所有实例。