在 Swift 中为游戏创建移动按钮

Create a moving Button for a Game in Swift

我有一项任务需要使用 SpriteKit 创建游戏。 它应该有一个在视图中随机移动的按钮,如果我点击它,我会得到分数。 问题是我不知道如何在 SpriteKit 中创建按钮。

我需要使用 SKSpriteNode 来解决问题吗?但是我怎样才能让它看起来像一个标准按钮呢?或者我真的可以为此创建一个按钮吗?

SpriteKit 没有built-inSKButtonclass。但我们可以构建一些基本功能。正如 sangony 所说,您需要三个部分:绘制图形(为简单起见,我使用 SKShapeNode,但您可以使用 SKSpriteNode);移动节点;添加拣货功能。这里有一些代码来说明。

绘制

SKShapeNodeSKSpriteNode 添加到您的 SKNode class

shape = SKShapeNode(circleOfRadius: 40)
shape.fillColor = .green
addChild(shape)

移动

SKAction 非常有用。这是一个移动到随机位置,然后递归调用自身的示例。 stop/go 由布尔标志调节。

func movement() {
    print("movement")
    let DURATION:CGFloat = 2.0
    let random_x = CGFloat.random(in: -200...200)
    let random_y = CGFloat.random(in: -200...200)
    let random_point = CGPoint(x: random_x, y: random_y)
    let move = SKAction.move(to: random_point, duration: DURATION)
    move.timingMode = .easeInEaseOut
    let wait = SKAction.wait(forDuration: DURATION)
    let parallel = SKAction.group([move,wait])
    
    let recursion = SKAction.run {
        if self.isInMotion { self.movement() }
    }
    let serial = SKAction.sequence([parallel, recursion])
    self.run(serial)
}

选择

测试场景中的用户点击称为拾取。我使用 PickableNode 协议来帮助筛选出您希望可点击的 SKNodes

extension GameScene {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        for touch in touches{
            //call `pick` on any `PickableNode` that exists at touch location
            let location = touch.location(in: self)
            let _ = self.nodes(at: location).map { ([=12=] as? PickableNode)?.pick() }
        }
    }
}

至此全部完成class

protocol PickableNode {
    func pick()
}

class Button: SKNode, PickableNode {
    let shape:SKShapeNode
    var isInMotion:Bool = true
    override init() {
        shape = SKShapeNode(circleOfRadius: 40)
        shape.fillColor = .green
        super.init()
        addChild(shape)
        movement()
    }
    
    required init?(coder aDecoder: NSCoder) {
        fatalError("init(coder:) has not been implemented")
    }
    
    func movement() {
        print("movement")
        let DURATION:CGFloat = 2.0
        let random_x = CGFloat.random(in: -200...200)
        let random_y = CGFloat.random(in: -200...200)
        let random_point = CGPoint(x: random_x, y: random_y)
        let move = SKAction.move(to: random_point, duration: DURATION)
        move.timingMode = .easeInEaseOut
        let wait = SKAction.wait(forDuration: DURATION)
        let parallel = SKAction.group([move,wait])
        
        let recursion = SKAction.run {
            if self.isInMotion { self.movement() }
        }
        let serial = SKAction.sequence([parallel, recursion])
        self.run(serial)
    }
    
    func pick() {
        print("i got picked")
        if !isInMotion {
            isInMotion = true
            shape.fillColor = .green
            movement()
        } else {
            isInMotion = false
            shape.fillColor = .red
            self.removeAllActions()
        }
    }
}