微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

如何在存在重力的情况下在 SpriteKit 中拖动和轻弹节点?

如何解决如何在存在重力的情况下在 SpriteKit 中拖动和轻弹节点?

使用我当前的代码,节点非常滞后,并且在轻弹时出于某种原因向随机方向移动或传送。我该如何解决这个问题,也有人可以解释为什么它会传送并移动到场景中的随机位置。

此外,是否允许仅在从其位置拖动节点时移动节点,而不是始终处于手势识别器的坐标处?


    override func didMove(to view: SKView) {
    let gestureRecognizer = UIPanGestureRecognizer(target: self,action: #selector(self.pan(_:)))
    

    view.addGestureRecognizer(gestureRecognizer)
    circleNode.physicsBody = SKPhysicsBody(circleOfRadius: 20)
    self.physicsWorld.gravity = CGVector(dx: 0,dy: 0)
    self.addChild(circleNode)
}


@objc func pan(_ recognizer: UIPanGestureRecognizer) {
   

    
    if recognizer.state == .changed {

        self.physicsWorld.gravity = CGVector(dx: 0,dy: 0)
        var location = recognizer.location(in: self.view!)
        location = self.convertPoint(fromView: location)
        
        
        circleNode.position = location
        
        
        
        
    }
    
    if recognizer.state == .ended {
        self.physicsWorld.gravity = CGVector(dx: 0,dy: -9.8)
        let transformerX = 1024/self.view!.frame.size.width
        let transformerY = 768/self.view!.frame.size.height
        let veLocity = recognizer.veLocity(in: self.view)
        circleNode.physicsBody?.applyForce(CGVector(dx: veLocity.x * transformerX,dy: veLocity.y * transformerY))



    }
    
    
    
}

   

解决方法

enter image description here下面是我在玩的一些代码。我能够拖动和轻弹长矛(矛图像),还可以“弹出”一个猪头。这是整个GameScene。删除您不需要的代码。 :)

 import SpriteKit
 import CoreMotion

class GameScene: SKScene,SKPhysicsContactDelegate  {

  enum CollisionTypes: UInt32{
    case spear = 1
    case wall = 2
    case head = 4
  }


  var touchPoint: CGPoint = CGPoint()
  var touching: Bool = false

override func didMove(to view: SKView) {
    self.physicsBody = SKPhysicsBody(edgeLoopFrom: self.frame)
    //Add contact delegate
    physicsWorld.contactDelegate = self
    self.backgroundColor = .white
    
    self.addChild(spearNode)
    self.addChild(headNode)
}



lazy var spearNode: SKSpriteNode = {
    let node = SKSpriteNode(imageNamed: "spear2")
    node.name = "Spear"
    node.physicsBody = SKPhysicsBody(texture: node.texture!,size: CGSize(width: node.frame.width,height: node.frame.height))
    node.position = CGPoint(x:self.frame.midX,y:self.frame.midY)
    node.physicsBody?.affectedByGravity = true
    node.physicsBody?.allowsRotation = false
    node.size = CGSize(width: node.frame.width,height: node.frame.height )
    node.physicsBody?.categoryBitMask = CollisionTypes.spear.rawValue
    node.physicsBody?.contactTestBitMask = CollisionTypes.head.rawValue
    node.physicsBody?.collisionBitMask = CollisionTypes.head.rawValue
    return node
}()

lazy var headNode: SKSpriteNode = {
    let node = SKSpriteNode(imageNamed: "Pig")
    node.name = "Pig"
    node.physicsBody = SKPhysicsBody(texture: node.texture!,y:self.frame.maxY - 100)
    node.physicsBody?.affectedByGravity = true
    node.physicsBody?.allowsRotation = false
    node.size = CGSize(width: node.frame.width / 2,height: node.frame.height / 2 )
    node.physicsBody?.categoryBitMask = CollisionTypes.head.rawValue
    return node
    
}()

func didBegin(_ contact: SKPhysicsContact){
    guard let nodeA = contact.bodyA.node else {return}
    guard let nodeB = contact.bodyB.node else {return}
    
    print("Contacted")
    
    if nodeA.name == "Pig" && nodeB.name == "Spear"{
        nodeA.removeFromParent() 
    }
    
    if nodeA.name == "Spear" && nodeB.name == "Pig"{    
        nodeB.removeFromParent()
    }
}


override func touchesBegan(_ touches: Set<UITouch>,with event: UIEvent?) {
    let touch = touches.first!
    let location = touch.location(in:self)
    
    if spearNode.frame.contains(location) {
        touchPoint = location
        touching = true
    }
}


override func touchesMoved(_ touches: Set<UITouch>,with event: UIEvent?) {
    let touch = touches.first!
    let location = touch.location(in: self)
    touchPoint = location
}

override func touchesEnded(_ touches: Set<UITouch>,with event: UIEvent?) {
    touching = false
}


override func update(_ currentTime: TimeInterval) {
    physicsWorld.gravity = CGVector(dx:0,dy: -9.8)
    
    if touching {
        let dt:CGFloat = 1.0/60.0
        let distance = CGVector(dx: touchPoint.x-spearNode.position.x,dy: touchPoint.y-spearNode.position.y)
        let velocity = CGVector(dx: distance.dx/dt,dy: distance.dy/dt)
        spearNode.physicsBody!.velocity=velocity
    }
  }
}
,

为什么不简单地根据滑动手势向对象施加力,而不是关闭重力,手动移动对象,然后在滑动结束后再次打开重力?

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。