拖动时选择多个节点

时间:2019-07-25 12:26:21

标签: swift sprite-kit 2d-games

我正在尝试制作一款游戏,玩家有时在屏幕上绘制图案。为此,我的解决方案是在屏幕上添加可通过扩展SKSpriteNode触摸的多个节点。 当玩家触摸一个节点时,我想调用touchesmoved,并将所有触摸的节点添加到数组中。 然后,当播放器停止触摸屏幕时,我想将该阵列与另一个阵列进行匹配,然后发生一些事情。

我一直在使用updates函数,并尝试在每个更新循环中运行一个函数,但是效果不是很好。我也尝试过使gameScene类成为我的touchableShapeNode类的委托,但是我努力使它起作用。

class TouchableShapeNode: SKShapeNode {
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if (name != nil) {
            print("\(name ?? "node") touched")

        }
    }

    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if (name != nil) { 
            print("\(name ?? "node") touched")

        }
    }
  }

我的问题是,现在唯一被选中的节点是我触摸的第一个节点,而不是玩家手指移过的那个节点。现在,我只是在打印触摸节点的名称。

1 个答案:

答案 0 :(得分:0)

我不确定您要做什么,但这是一个执行以下操作的小程序:

  1. 在屏幕上放置15个红色方块
  2. 在屏幕上拖动时,您触摸的所有节点都会添加到集合中。
  3. 停止触摸时,所有触摸的节点的颜色都变为绿色。
  4. 开始新的触摸时,将清空所有触摸的节点,并且所有节点都将恢复其初始颜色(红色)。

要使用,只需启动一个新的空SpriteKit项目,然后用此代码替换gameScene.swift。

import SpriteKit
import UIKit

class GameScene: SKScene {

    let shipSize = CGSize(width: 25, height: 25)
    let normalColour = UIColor.red
    let touchedColour = UIColor.green
    var touchedNodes = Set<SKSpriteNode>()

    override func didMove(to view: SKView) {

        let sceneWidth = self.scene?.size.width
        let sceneHeight = self.scene?.size.height

        // Add 15 colour sprites to the screen in random places.
        for _ in 1...15 {
            let ship = SKSpriteNode(color: normalColour, size: shipSize)
            ship.position.x = CGFloat.random(in: -sceneWidth!/2...sceneWidth!/2) * 0.7
            ship.position.y = CGFloat.random(in: -sceneHeight!/2...sceneHeight!/2) * 0.7
            ship.name = "ship"
            addChild(ship)
        }
    }

    // When the screen is toucheed, empty the 'touchedNodes' set and rest all nodes back to their normal colour.
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        resetTouchedNodes()
    }

    // As the touch moves, if we touch a node then add it to our 'touchedNodes' set.
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        let touch = touches.first
        let location = touch!.location(in: self)

        // If there is a node at the touch location, add it to our 'touchedSprites' set.
        if let touchedNode = selectNodeForTouch(location) {
            touchedNodes.insert(touchedNode)
        }
    }

    // When the touch ends, make all nodes that were touched change colour.
    override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
        for node in touchedNodes {
            node.color = touchedColour
        }
    }

    override func touchesCancelled(_ touches: Set<UITouch>, with event: UIEvent?) {
        resetTouchedNodes()
    }

    // Return the first sprite where the user touched the screen, else nil
    func selectNodeForTouch(_ touchLocation: CGPoint) -> SKSpriteNode? {
        let nodes = self.nodes(at: touchLocation)
        for node in nodes {
            if node is SKSpriteNode {
                return (node as! SKSpriteNode)
            }
        }
        return nil
    }

    // Clear the touchedSprites set and return all nodes on screen to their normal colour
    func resetTouchedNodes() {
        touchedNodes.removeAll()
        enumerateChildNodes(withName: "//ship") { node, _ in
            let shipNode = node as! SKSpriteNode
            shipNode.color = self.normalColour
        }
    }

}

您可以通过多种方式对此进行修改。例如,您可以在touchesMoved等中触摸精灵,立即更改其颜色。