Select 拖动时有多个节点
Select multiple nodes while dragging
我正在尝试制作一款游戏,让玩家在特定时间在屏幕上绘制图案。我的解决方案是通过 SKSpriteNode 的扩展在屏幕上添加多个可触摸的节点。
当玩家触摸到一个节点时,我想调用 touchesmoved,并将所有触摸到的节点添加到一个数组中。
然后,当玩家停止触摸屏幕时,我想将该数组与另一个数组匹配,然后发生了一些事情。
我一直在尝试更新函数,并尝试 运行 每个更新循环都有一个函数,但效果不是很好。我也试过让 gameScene class 成为我的 touchableShapeNode Class 的代表,但我很难让它发挥作用。
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")
}
}
}
我的问题是现在唯一被选中的节点是我触摸的第一个节点,而不是玩家手指移过的节点。现在我只是打印触摸节点的名称。
我不太确定你在找什么,但这里有一个小程序可以执行以下操作:
- 在屏幕上放置 15 个红色方块
- 当您在屏幕上拖动时,您触摸的任何节点都会添加到一个集合中。
- 当您停止触摸时,所有触摸的节点的颜色都会变为绿色。
- 当您开始新的触摸时,触摸的节点集被清空并且所有节点return变为它们的起始颜色(红色)。
要使用,只需启动一个新的空 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
等
时立即更改精灵的颜色
我正在尝试制作一款游戏,让玩家在特定时间在屏幕上绘制图案。我的解决方案是通过 SKSpriteNode 的扩展在屏幕上添加多个可触摸的节点。 当玩家触摸到一个节点时,我想调用 touchesmoved,并将所有触摸到的节点添加到一个数组中。 然后,当玩家停止触摸屏幕时,我想将该数组与另一个数组匹配,然后发生了一些事情。
我一直在尝试更新函数,并尝试 运行 每个更新循环都有一个函数,但效果不是很好。我也试过让 gameScene class 成为我的 touchableShapeNode Class 的代表,但我很难让它发挥作用。
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")
}
}
}
我的问题是现在唯一被选中的节点是我触摸的第一个节点,而不是玩家手指移过的节点。现在我只是打印触摸节点的名称。
我不太确定你在找什么,但这里有一个小程序可以执行以下操作:
- 在屏幕上放置 15 个红色方块
- 当您在屏幕上拖动时,您触摸的任何节点都会添加到一个集合中。
- 当您停止触摸时,所有触摸的节点的颜色都会变为绿色。
- 当您开始新的触摸时,触摸的节点集被清空并且所有节点return变为它们的起始颜色(红色)。
要使用,只需启动一个新的空 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
等