我试图让节点位于触摸位置,但遇到了 .nodes() 返回父节点和位于同一“位置”的其他节点的问题。
我已经尝试了十几种不同的代码配置,但似乎无法找到使用 SKScene.convert() 或 SKScene.convertPoint() 的正确顺序和其他人....
基本上,我有一个垂直层次的节点树。顶部是父节点,下面的每个节点都是直接在顶部的节点的子节点...(见下图)
当我点击最底部的节点时,在我的场景中运行 .nodes() 得到了多次点击……我试图只获取我指定位置的节点单击...当我单击某处时,我不希望打印相同“位置”或相同“.position”的父节点或其他节点...我只是想只获取精确位置的节点我触摸...
这是我正在使用的图片...当您单击/点击屏幕时,它会打印出哪些节点位于触摸位置:
这是我的点击代码(记住,每个节点从上到下都在父/子节点中,它的 SKNode.name 只是一个数字作为标识符):
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let allNodes = nodes(at: touches.first!.location(in: self))
for node in allNodes { print( node.name! ) }
}
我已经尝试了十几种不同的方法来将触摸点转换为 UIView 或 SKNode 坐标等。我无法正确...这里是我点击右下节点时的输出:
(同样,数字只是创建顺序中节点的名称...):
8
7
5
4
2
1
当我点击右下角的节点时,应该只会打印 1-2 个节点,但我却打印了 6 个节点...这是因为它们的 .postion 是“相同的” “我有时相信 SK 的困惑坐标系统 =/
因此,我的解决方法是创建一个基于 Y 值的过滤器……换句话说,只有我单击的一般区域周围的节点才会被打印……但我的操作已经很密集了,所以我试图不必为此列表创建过滤器...
我真的认为有一种方法可以在我点击的地方获取节点
但我一直无法找出 .nodes() 和 .location(in:) 的正确组合来实现这一点。
我试过玩 .atPoint 并从那里使用 .position,但一点运气都没有..
我现在迷路了,不想创建文件管理器:{
最佳答案
如果我了解到您的项目中有节点,其中每个节点都有不同的父节点。当你点击屏幕时你触摸了一个特定的点,但是这个点是在当前场景“self”(你有 touchesBegan 的类)上检测到的,所以当你触摸 releationship parent/中最深的节点时 child 接触的节点也显示了他的 parent 。
但是你只想要触摸点可见区域中涉及的节点/节点,所以我认为在这种情况下你可以做的是获取转换为当前类(self)的每个节点的框架并检查触摸点是否包含在此框架中。
在下面的这个例子中我使用了 4 个节点:
import SpriteKit
class GameScene: SKScene {
var node5:SKSpriteNode!
var node6:SKSpriteNode!
var node7:SKSpriteNode!
var node8:SKSpriteNode!
override func didMove(to view: SKView) {
let startPos = CGPoint(x:self.frame.midX,y:self.frame.midY)
node5 = SKSpriteNode.init(color: .yellow, size: CGSize(width:50,height:60))
self.addChild(node5)
node5.name = "5"
node5.position = CGPoint(x:startPos.x+35,y:startPos.y-180)
node6 = SKSpriteNode.init(color: .blue, size: CGSize(width:50,height:60))
node5.addChild(node6)
node6.name = "6"
node6.position = CGPoint(x:60,y:0)
node7 = SKSpriteNode.init(color: .green, size: CGSize(width:80,height:60))
node6.addChild(node7)
node7.name = "7"
node7.position = CGPoint(x:60,y:10)
node8 = SKSpriteNode.init(color: .red, size: CGSize(width:80,height:60))
node7.addChild(node8)
node8.name = "8"
node8.position = CGPoint(x:-10,y:20)
}
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
let touch = touches.first
let positionInScene = touch!.location(in: self)
let allNodes = nodes(at: positionInScene)
for node in allNodes {
let nodePositionConverted = self.convert(node.position, from: node)
let nodeFrameConverted = CGRect(origin: CGPoint(x:nodePositionConverted.x-node.frame.maxX,y:nodePositionConverted.y-node.frame.maxY),size:node.frame.size)
if nodeFrameConverted.contains(positionInScene), let n = node.name {print(n)}
}
}
}
输出:
此输出显示不同的水龙头。第一次点击涉及 3 个节点,红色的 8,绿色的 7 和蓝色的 6。确实,您将不得不使用调试控制台:
第二次点击仅涉及绿色 7 和蓝色 6:<>
第三次和第四次点击仅涉及蓝色和黄色节点,因此您分别只有触摸的每个节点的数量。
最后一次点击涉及到红色 8 和蓝色 6,所以你有:
希望这对您的触摸处理有所帮助。
>
关于swift - `SKScene.nodes()` 为触摸位置提供了太多节点,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/41775829/
我需要一个非常简单的字符串验证器来显示第一个符号与所需格式不对应的位置。我想使用正则表达式,但在这种情况下,我必须找到与表达式相对应的字符串停止的位置,但我找不到可以做到这一点的方法。(这一定是一种相当简单的方法……也许没有?)例如,如果我有正则表达式:/^Q+E+R+$/带字符串:"QQQQEEE2ER"期望的结果应该是7 最佳答案 一个想法:你可以做的是标记你的模式并用可选的嵌套捕获组编写它:^(Q+(E+(R+($)?)?)?)?然后你只需要计算你获得的捕获组的数量就可以知道正则表达式引擎在模式中停止的位置,你可以确定匹配结束
我将Cucumber与Ruby结合使用。通过Selenium-Webdriver在Chrome中运行测试时,我想将下载位置更改为测试文件夹而不是用户下载文件夹。我当前的chrome驱动程序是这样设置的:Capybara.default_driver=:seleniumCapybara.register_driver:seleniumdo|app|Capybara::Selenium::Driver.new(app,:browser=>:chrome,desired_capabilities:{'chromeOptions'=>{'args'=>%w{window-size=1920,1
我想在heroku.com上查看我的应用程序日志的内容,所以我关注了thisexcellentadvice并拥有我所有的日志内容。但是我现在很想知道我的日志文件实际在哪里,因为“log/production.log”似乎是空的:C:\>herokuconsoleRubyconsoleforajpbrevx.heroku.com>>files=Dir.glob("*")=>["public","tmp","spec","Rakefile","doc","config.ru","app","config","lib","README","Gemfile.lock","vendor","sc
这应该是一个简单的问题,但我找不到任何相关信息。给定一个Ruby中的正则表达式,对于每个匹配项,我需要检索匹配的模式$1、$2,但我还需要匹配位置。我知道=~运算符为我提供了第一个匹配项的位置,而string.scan(/regex/)为我提供了所有匹配模式。如果可能,我需要在同一步骤中获得两个结果。 最佳答案 MatchDatastring.scan(regex)do$1#Patternatfirstposition$2#Patternatsecondposition$~.offset(1)#Startingandendingpo
为了在我的mac上为一个rails项目安装mysql,我遵循了安装Homebrew软件和删除mac端口的在线建议。这是问题开始的地方。rails项目不会构建,我得到这个:[rake--prereqs]rakeaborted!dlopen(/Users/Parker/.rvm/gems/ruby-1.9.3-p448/gems/nokogiri-1.6.0/lib/nokogiri/nokogiri.bundle,9):Librarynotloaded:/opt/local/lib/libiconv.2.dylibReferencedfrom:/Users/Parker/.rvm/gem
我使用“newapp_name”创建了一个新的Rails应用程序,我正在尝试编辑.gitignore文件,但在我的应用程序文件夹中找不到它。我在哪里可以找到它?我安装了Git。 最佳答案 .gitignore位于项目的root中,而不是app子目录中。首先打开终端并进入您的目录。您需要使用ls-a来显示stash文件。然后使用打开.gitignore 关于ruby-on-rails-尝试打开.gitignore以在文本编辑器中对其进行编辑,但在OSXMountainLion上找不到文件位
我有一个Rails2.3.5应用程序,其中包含我希望保护的API。没有用户-它是一个应用到应用风格的网络服务(更像是亚马逊服务而不是facebook),所以我想使用两条腿的OAuth方法来实现它。我一直在尝试使用oauth-plugin服务器实现作为开始:http://github.com/pelle/oauth-plugin...但它的构建需要三足(网络重定向流)oauth。在我深入研究对其进行更改以支持两条腿之前,我想看看是否有更简单的方法,或者是否有人有更好的方法让Rails应用程序实现成为两条腿的OAuth提供程序。 最佳答案
对于我正在编写的Rails3应用程序,我正在考虑从本地文件系统上的XML、YAML或JSON文件中读取一些配置数据。重点是:我应该把这些文件放在哪里?Rails应用程序中是否有用于存储此类内容的默认位置?附带说明一下,我的应用程序部署在Heroku上。 最佳答案 我经常做的是:如果文件是通用配置文件:我在目录/config中创建一个YAML文件,每个环境有一个上层key如果我为每个环境(大项目)创建一个文件:我为每个环境创建一个YAML并将它们存储在/config/environments/然后我在加载YAML的地方创建了一个初始化
假设我有一个没有特定顺序的随机数数组。假设这些是参加马拉松比赛的人的ID#,他们按照完成的顺序添加到数组中,例如:race1=[8,102,67,58,91,16,27]race2=[51,31,7,15,99,58,22]这是一个简化且有些做作的示例,但我认为它传达了基本思想。现在有几个问题:首先,我如何获得特定条目之前和之后的ID?假设我正在查看运行者58,我想知道谁在他之前和之后完成了比赛。race1,runner58:previousfinisher=67,nextfinisher=91race2,runner58:previousfinisher=99,nextfinishe
我有一个包含多个组件的存储库,其中大部分是用JavaScript(Node.js)编写的,一个是用Ruby(RubyonRails)编写的。我想要一个.travis.yml文件来触发一个运行每个组件的所有测试的构建。根据thisTravisCIGoogleGroupthread,目前还没有官方支持。我的目录结构是这样的:.├──构建服务器├──核心├──扩展├──网络应用├──流浪文件├──package.json├──.travis.yml└──生成文件我希望能够运行特定版本的Ruby(2.2.2)和Node.js(0.12.2)。我已经有了一个make目标,所以maketest在每