Ios nodeAtPoint错误节点
我正在用swift和spritekit制作一个游戏,我有一个功能,可以让多个精灵从屏幕顶部掉落。我还制作了它,这样我就可以使用nodeAtPoint检测到精灵上的触摸,并可以轻弹精灵。我的问题是,由于nodeAtPoint拖动树中最深的节点,当我单击并拖动精灵时,场景中最新的精灵会被拉向我的触摸方向,而不是我最初触摸的那个。如果有人对如何只影响我接触的节点有一些建议,我会非常感激Ios nodeAtPoint错误节点,ios,swift,sprite-kit,Ios,Swift,Sprite Kit,我正在用swift和spritekit制作一个游戏,我有一个功能,可以让多个精灵从屏幕顶部掉落。我还制作了它,这样我就可以使用nodeAtPoint检测到精灵上的触摸,并可以轻弹精灵。我的问题是,由于nodeAtPoint拖动树中最深的节点,当我单击并拖动精灵时,场景中最新的精灵会被拉向我的触摸方向,而不是我最初触摸的那个。如果有人对如何只影响我接触的节点有一些建议,我会非常感激 class GameScene: SKScene { var ball = SKSpriteNod
class GameScene: SKScene {
var ball = SKSpriteNode(imagedNamed: "blueBlue")
var touchedNode: SKNode? = SKNode()
override func didMoveToView(view: SKView) {
var create = SKAction.runBlock({() in self.createTargets()})
var wait = SKAction.waitForDuration(2)
var waitAndCreateForever = SKAction.repeatActionForever(SKAction.sequence([create, wait]))
self.runAction(waitAndCreateForever)
}
func createTargets() {
ball = SKSpriteNode(imageNamed: "blueBlue")
let randomx = Int(arc4random_uniform(170) + 290)
ball.zPosition = 0
ball.physicsBody = SKPhysicsBody(circleOfRadius: ball.size.width / 11)
ball.physicsBody?.dynamic = true
ball.size = CGSize(width: ball.size.width / 1.5, height: ball.size.height / 1.5)
let random = Int(arc4random_uniform(35))
let textures = [texture1, texture2, texture3, texture4, texture5, texture6, texture7, texture8, texture9, texture10, texture11, texture12, texture13, texture14, texture15, texture16, texture17, texture18, texture19, texture20, texture21, texture22, texture23, texture24, texture25, texture1, texture7, texture18, texture24, texture25, texture1, texture7, texture18, texture24, texture25]
ball.texture = textures[random]
ball.position = CGPoint(x: randomx, y: 1400)
addChild(ball)
}
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInNode(self)
touchedNode = self.nodeAtPoint(touchLocation)
if touchedNode.frame.contains(touchLocation) {
touching = true
touchPoint = touchLocation
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInNode(self)
touching = true
touchPoint = touchLocation
}
override func update(currentTime: NSTimeInterval) {
if touching {
if touchPoint != touchedNode.position {
let dt: CGFloat = 0.1
let distance = CGVector(dx: touchPoint.x - touchedNode.position.x, dy: touchPoint.y - touchedNode.position.y)
let vel = CGVector(dx: distance.dx / dt, dy: distance.dy / dt)
if touchedNode.parent != nil {
touchedNode.physicsBody?.velocity = vel
}
}
}
}
}
class游戏场景:SKScene{
var ball=SKSpriteNode(图像名称:“蓝蓝蓝”)
var touchedNode:SKNode?=SKNode()
覆盖func didMoveToView(视图:SKView){
var create=SKAction.runBlock({()在self.createTargets()中)
var wait=SKAction.waitForDuration(2)
var waitAndCreateForever=SKAction.repeatActionForever(SKAction.sequence([create,wait]))
self.runAction(waitAndCreateForever)
}
func createTargets(){
ball=SKSpriteNode(图像名为:“蓝蓝蓝”)
设randomx=Int(arc4random_均匀(170)+290)
ball.zPosition=0
ball.physicsBody=SKPhysicsBody(圆形半径:ball.size.width/11)
ball.physicsBody?动态=真
ball.size=CGSize(宽度:ball.size.width/1.5,高度:ball.size.height/1.5)
设random=Int(arc4random_均匀(35))
让纹理=[纹理1、纹理2、纹理3、纹理4、纹理5、纹理6、纹理7、纹理8、纹理9、纹理10、纹理11、纹理12、纹理13、纹理14、纹理15、纹理16、纹理17、纹理18、纹理19、纹理20、纹理21、纹理22、纹理23、纹理24、纹理25、纹理17、纹理18、纹理18、纹理18、纹理18,纹理24,纹理25]
ball.texture=纹理[随机]
ball.position=CGPoint(x:randomx,y:1400)
addChild(球)
}
覆盖func touchesBegined(触摸:设置,withEvent事件:UIEvent){
让touch=touch.first as!UITouch
让touchLocation=touch.locationInNode(自身)
touchedNode=self.nodeAtPoint(touchLocation)
如果touchedNode.frame.contains(触摸位置){
触摸=真实
接触点=接触位置
}
}
覆盖功能触摸移动(触摸:设置,withEvent事件:UIEvent){
让touch=touch.first as!UITouch
让touchLocation=touch.locationInNode(自身)
触摸=真实
接触点=接触位置
}
覆盖函数更新(当前时间:NSTimeInterval){
如果接触{
如果接触点!=touchedNode.position{
设dt:CGFloat=0.1
让距离=CGVector(dx:touchPoint.x-touchedNode.position.x,dy:touchPoint.y-touchedNode.position.y)
设vel=CGVector(dx:distance.dx/dt,dy:distance.dy/dt)
如果touchedNode.parent!=nil{
touchedNode.physicsBody?.velocity=vel
}
}
}
}
}
我建议您对代码进行以下更改:
受重力影响的属性
touched节点
和触摸
变量触摸开始
和触摸移动
替换为以下内容
override func touchesBegan(touches: Set<NSObject>, withEvent event: UIEvent) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInNode(self)
if (!touching) {
let node = self.nodeAtPoint(touchLocation)
if node is SKSpriteNode {
touchedNode = node
touching = true
touchPoint = touchLocation
touchedNode!.physicsBody?.affectedByGravity = false
}
}
}
override func touchesMoved(touches: Set<NSObject>, withEvent event: UIEvent) {
if (touching) {
let touch = touches.first as! UITouch
let touchLocation = touch.locationInNode(self)
touchPoint = touchLocation
}
}
override func touchsbegined(touchs:Set,withEvent-event:UIEvent){
让touch=touch.first as!UITouch
让touchLocation=touch.locationInNode(自身)
如果(!触摸){
让node=self.nodeAtPoint(touchLocation)
如果节点是SKSpriteNode{
touchedNode=节点
触摸=真实
接触点=接触位置
touchedNode!.physicsBody?.affectedByGravity=false
}
}
}
覆盖功能触摸移动(触摸:设置,withEvent事件:UIEvent){
如果(触摸){
让touch=touch.first as!UITouch
让touchLocation=touch.locationInNode(自身)
接触点=接触位置
}
}
并添加此方法
override func touchesEnded(touches: Set<NSObject>, withEvent event: UIEvent) {
if (touchedNode != nil) {
touchedNode!.physicsBody!.affectedByGravity = true
}
touchedNode = nil
touching = false
}
override func touchesend(touchs:Set,withEvent-event:UIEvent){
if(touchedNode!=nil){
touchedNode!.physicsBody!.affectedByGravity=true
}
touchedNode=nil
触摸=错误
}
嘿,谢谢你的建议。我使用了你的代码,不幸的是我仍然有同样的问题。但是我注意到,如果我让节点陷得更深一点,我可以成功地拖动我单击的节点。也许这可以帮助我尝试做什么?我没有遇到你描述的问题,我看不到这是怎么发生的ing提供了代码。我可以正确选择并拖动从屏幕顶部掉落的精灵。我没有发布完整的代码,因此可能代码中有其他内容干扰了它。总之,这一切都很好,因为我将游戏更改为不需要拖动这些节点。再次感谢不确定这是否有助于您,但请参见:@EpicByte looks就像OP的代码是基于你的帖子。我发现很有趣的是,代码设置了移动物理体的速度,而不是使用力或脉冲。我从其他人那里得到了代码,他们可能是从你的帖子中得到的。@0x141E我总是选择直接设置速度,而不是通过applyImpulse/force方法间接设置速度,特别是如果我正在执行自定义实时计算,例如移动到某个点,模拟浮力等,它也会稍微快一点,让我完全控制计算。我应用冲量和力的唯一时间是在我不进行计算的情况下