我有一个游戏菜单,显示多个成就,定义为SKSpriteNodes,其中有18个,并且它们的定位只有轻微的变化,这里是代码片段:
Achievement1 = SKSpriteNode(color: SKColor.whiteColor(), size: CGSize(width: 100, height: 100))
Achievement1.position = CGPointMake(-120, 100)
page1ScrollView.addChild(Achievement1)
Achievement2 = SKSpriteNode(color: SKColor.whiteColor(), size: CGSize(width: 100, height: 100))
Achievement2.position = CGPointMake(0, 100)
page1ScrollView.addChild(Achievement2)
Achievement3 = SKSpriteNode(color: SKColor.whiteColor(), size: CGSize(width: 100, height: 100))
Achievement3.position = CGPointMake(120, 100)
page1ScrollView.addChild(Achievement3)
Achievement4 = SKSpriteNode(color: SKColor.whiteColor(), size: CGSize(width: 100, height: 100))
Achievement4.position = CGPointMake(-120, -25)
page1ScrollView.addChild(Achievement4)
此外,我已经竭尽全力将它们逐一定义为vars,如下所示:
var Achievement1: SKSpriteNode!
var Achievement2 = SKSpriteNode()
var Achievement3 = SKSpriteNode()
var Achievement4 = SKSpriteNode()
var Achievement5 = SKSpriteNode()
var Achievement6 = SKSpriteNode()
var Achievement7 = SKSpriteNode()
var Achievement8 = SKSpriteNode()
它看起来像一团糟,只占用太多空间。我希望能够定义所有的精灵节点,并让它们都能够被按下以显示一个框,其中说明了成就是什么样的:
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: UITouch = touches.first!
let location: CGPoint = touch.locationInNode(self)
let node: SKNode = self.nodeAtPoint(location)
if (node == Achievement1) {
//achievement details here
}
我仍然对这种快速的语言不熟悉而且我不是很先进但我会很感激帮助。
答案 0 :(得分:3)
如果您认为代码很乱,请尝试在代码中找到模式。
查看Achievement1
,Achievement2
,Achievement3
,Achievement4
个东西?当你看到这种模式时,你应该创建一个数组来存储成就。
我确定你知道如何使用数组,所以我不会谈论太多。有关详细信息,您可以转到Array
类的定义。
您可能会注意到的另一种模式是使用相同的参数来创建精灵节点。成就之间的唯一区别在于他们的立场。
解决此问题的最佳方法是创建方法:
func createAchievement(location: CGPoint) -> SKSpriteNode {
let node = SKSpriteNode(color: SKColor.whiteColor(), size: CGSize(width: 100, height: 100))
node.position = location
return node
}
您只需要一行就可以为上述阵列添加新成就:
someArray.append(createAchievement(CGPointMake(-120, 100)))
编辑:
如果你使用indexOf(_:)
(或swift 3中的index(of:)
),你可以创建一个switch语句而不是if语句:
switch someArray.indexOf(node) {
case 0:
// this means that the first achievement is tapped!
case 1:
// this means that the second achievement is tapped!
case 2:
// this means that the third achievement is tapped!
}
答案 1 :(得分:1)
关于当您要显示大量项目时的布局,您可以考虑使用表格或页面控件。因为我很懒,所以我不喜欢滚动表只看到所有的游戏成就,所以通常我会首先使用PageControl。
您可以在UIKit
内置UIPageControl
并将其集成到游戏菜单中。
如果您不知道如何集成UIPageControl
,可以使用此精灵工具包项目 GBPageControl
import GBPageControl
var pageControl:PageControl!
//Add the page control to the scene. Add any content that will be paged directly to the pageControl:
override func didMoveToView(view: SKView) {
pageControl = PageControl(scene: self)
addContent()
pageControl.enable(4)
}
private func addContent() {
for var i = 0; i < 4; i++ {
let node = SKShapeNode(circleOfRadius: 10)
node.strokeColor = UIColor.blueColor()
let x = self.size.width / 2.0 + self.size.width * CGFloat(i)
let y = self.size.height / 2.0
node.position = CGPoint(x:x, y:y)
pageControl.addChild(node)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
for touch in touches {
if pageControl.handleTouch(touch) {
//no op
}
else {
//handle touch
}
}
}
override func willMoveFromView(view: SKView) {
pageControl.willMoveFromView(view)
}
<强>输出强>:
<强>更新强>:
关于您可以尝试的成就代码:
enum MedalType: Int {
case Gold = 1
case Silver = 2
case Bronze = 3
}
class Achievement:SKSpriteNode {
init(color:SKColor,size:CGSize,name:String,medalType:MedalType) {
super.init(texture: nil,color:color,size:size)
self.name = name
}
required init?(coder aDecoder: NSCoder) {
fatalError("init(coder:) has not been implemented")
}
}
class GameScene: SKScene {
var achievements:[Achievement]!
var aNames: [String]!
var totalAchievements: Int = 45
override func didMoveToView(view: SKView) {
var counter : Int = 0
let deltaX:CGFloat = 120
let deltaY:CGFloat = 10
for i in 0..<totalAchievements {
var aColor = SKColor.whiteColor()
var aSize = CGSizeMake(100,100)
var medal = MedalType.Bronze
switch i {
case 10:
aColor = SKColor.redColor()
aSize = CGSizeMake(100,150)
medal = MedalType.Silver
case 25:
aColor = SKColor.blueColor()
aSize = CGSizeMake(100,200)
medal = MedalType.Gold
default:
break
}
let name = "achievement\(i)"
let a = Achievement.init(color: aColor, size: aSize, name: name, medalType: medal)
aNames.append(name)
//handle your position has you wish with counter, deltaX e deltaY
//...
a.position = CGPointMake(deltaX, deltaY)
addChild(a)
}
}
override func touchesBegan(touches: Set<UITouch>, withEvent event: UIEvent?) {
let touch: UITouch = touches.first!
let location: CGPoint = touch.locationInNode(self)
let node: SKNode = self.nodeAtPoint(location)
if (aNames.contains(node.name!)) {
print("You have touch achievement \(node.name)")
let currentAchievement = achievements[aNames.indexOf(node.name!)!]
// Use your currentAchievement touched
}
}
}
答案 2 :(得分:0)
您可以使用数组......
let achievements = [SKSpriteNode](repeating: SKSpriteNode(color: SKColor.white(), size: CGSize(width: 100, height: 100)), count: 8) // Swift 3 colour name
let positions = [CGPoint(x: -120, y: 100), CGPoint(x: 0, y: 100) /* ... */]
for i in 0 ..< min(achievements.count, positions.count) { // For safety - obviously these should be the same
achievements[i].position = positions[i]
}
// Then in your touch routine...
if let index = achievements.index(of: self.nodeAtPoint(location)) {
// do something with achievements[index]
}
...并且不要将变量大写 - Swift惯例是只有类型大写......