【问题标题】:How to shoot a moving sprite in Swift?如何在 Swift 中拍摄移动的精灵?
【发布时间】:2018-01-13 21:36:17
【问题描述】:

我正试图让我的静止怪物向我移动的玩家射击。玩家位置和怪物位置都在获取正确的值,并且此代码编写在每秒调用的函数中。现在弹丸出现了,但并没有从怪物身上移开。除了 .applyAngularImpulse 之外,我还应该使用其他东西吗?

    let deltaX = player.position.x - monster.position.x
    let deltaY = player.position.y - monster.position.y
    let angle = atan2(deltaY, deltaX)

    monProjectile.physicsBody?.applyAngularImpulse(angle)

【问题讨论】:

  • 是的,我有。不幸的是,我对这些想法的应用似乎没有奏效,因为我试图在稍微不同的情况下使用它们。不过感谢您的帮助!
  • 没有物理的东西:stackoverflow.com/questions/36230619/… ... 不过,您可以将物理体添加到节点(只需设置node.physicsBody.affectedByGravity = false,并设置node.physicsBody.collisionBitMask = 0),以便进行接触检测。

标签: ios swift sprite-kit


【解决方案1】:

更新

查看您提供的代码后,我怀疑有两个问题:

1) 您正在指定一个我在您的项目中看不到的“射弹”图像。

2) 您正在尝试应用角脉冲(即旋转)而不是常规脉冲(即方向加速度)。

要解决第一个问题,请为您的弹丸添加图像。要解决第二个问题,请考虑使用 applyImpulse()CGVector

原答案

在我的脑海中,有几件事可能会导致这种情况:

1) 你施加了多大的冲动?打印出值并查看您使用的数字类型。

2) 你的射弹在怪物创建时会与怪物重叠吗?如果是这样,它可能会发生碰撞并卡住。

3) 弹丸是否有可能与其他节点完全碰撞,例如背景图片?

您应该考虑将您的SKViewshowsPhysics 设置为true,这样您就可以更清楚地看到发生了什么。

【讨论】:

  • 1.它说它正在应用大约 -3 值作为力。我认为这是正确的,因为我的玩家使用 3.0 进行投篮,而怪物在玩家的右侧,这就是为什么我相信我会得到一个负值。 2. 我设置了弹丸的位置,使其不会与精灵重叠(我已经遇到了玩家射击的问题)。 3. 我也不认为会是这样,因为玩家的射击效果很好,而且使用的是相同的方法,只是施加了不同的力量。感谢您的帮助!
  • 我刚刚在 /r/swift 上读到了同样的帖子,我想到了另一个选择:你的项目肯定有一个物理实体吗?试着把问号改成感叹号:如果你的代码崩溃了,你就犯了错误。
  • 我也试过了,没什么区别。应用不会崩溃。
  • 你能把你的项目贴在某个地方供我们下载和查看吗?
【解决方案2】:
func makeShoot() {
    let Shoot:ShootClass = ShootClass.init()
    Shoot.physicsBody = SKPhysicsBody(texture: Shoot.texture!,
                                     size: Shoot.texture!.size())
    Shoot.position = (self.Shoot?.position)!
    Shoot.currentPosition = (self.Shoot?.position)!
    Shoot.physicsBody?.isDynamic = true
    Shoot.physicsBody?.allowsRotation = false
    Shoot.physicsBody?.affectedByGravity = false
    Shoot.physicsBody?.friction = 0
    Shoot.physicsBody?.restitution = 1
    Shoot.physicsBody?.mass = 1
    Shoot.physicsBody?.linearDamping = 0.0
    Shoot.physicsBody?.angularDamping = 0.0
    Shoot.physicsBody?.categoryBitMask = ShootCategory
    Shoot.physicsBody?.collisionBitMask = BorderCategory
    Shoot.physicsBody?.contactTestBitMask = BorderCategory

    PlayingView.addChild(Shoot);

    Shoot.physicsBody?.applyImpulse(CGVector(dx: 100, dy: 100))

    self.moveNodeToLocation(Shoot: Shoot)
}



override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
    let curTouch = touches.first!
    let curPoint = curTouch.location(in: self)
    if ((curPoint.x > 103.5 && curPoint.y > 50.0) || (curPoint.x < 840.0 && curPoint.y > 50.0)) {
        StartingPoint = touches.first?.location(in: self)
        direction?.isHidden = false
        direction?.setScale(0.50)
        FirstTouchLocater = SKSpriteNode(imageNamed: "ic_Shootz");
        FirstTouchLocater.position = curPoint
        FirstTouchLocater.alpha = 0.5
        self.addChild(FirstTouchLocater);

    }
    else{
        self.direction?.isHidden = true
    }
}

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

    let point:CGPoint = (touches.first?.location(in: self))!

    if point.y < 40 {
        return
    }

    if !(isTouch!) {
        isTouch = true
    }


    let dy:CGFloat = StartingPoint!.y - point.y

    let size:CGFloat = dy*10/self.frame.height

    if size < 2 && size > 0.50 {
        direction?.setScale(size)
    }
     print("size ======> \(size)")




    let curTouch = touches.first!
    let curPoint = curTouch.location(in: self)

    if (curPoint.x <= ((StartingPoint?.x)! + 20.0)) &&  ((curPoint.x + 20.0) >= (StartingPoint?.x)!) && (curPoint.y <= ((StartingPoint?.y)! + 20.0)) &&  ((curPoint.y + 20.0) >= (StartingPoint?.y)!){
        self.direction?.isHidden = true
        FirstTouchLocater?.isHidden = true
    }
    else if ((curPoint.x > 103.5 && curPoint.y > 50.0) || (curPoint.x < 840.0 && curPoint.y > 50.0)) {
        let deltaX = (self.direction?.position.x)! - curPoint.x
        let deltaY = (self.direction?.position.y)! - curPoint.y
        let angle = atan2(deltaY, deltaX)

        let DegreesToRadians = CGFloat.pi / 180

        self.direction?.zRotation = angle + 90 * DegreesToRadians
        self.direction?.isHidden = false
        FirstTouchLocater?.isHidden = false
    }
    else{
        self.direction?.isHidden = true
        FirstTouchLocater?.isHidden = true
    }
}

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if direction?.isHidden == false {
        FirstTouchLocater.removeFromParent()
        direction?.isHidden = true
        direction?.setScale(0.1)
        if timeThrow == nil && isTouch!
        {
            isTouch = false
            counterY = 0;

            let touch = touches.first
            let touchLocation = touch?.location(in: self)
            lastTouch = touchLocation
            lastTouch1 = touchLocation

            ShootThrow = 2

            timeThrow = Timer.scheduledTimer(timeInterval: 0.1, target: self, selector: #selector(self.loadScreen), userInfo: nil, repeats: true)
        }
    }
}

func moveNodeToLocation(Shoot:SKSpriteNode) {
    let dx = (lastTouch?.x)! - Shoot.position.x
    let dy = (lastTouch?.y)! - Shoot.position.y

    let speed1:CGFloat = 424
    let hypo = hypot(dx, dy)

    let newX = (speed1 * dx) / hypo
    let newY = (speed1 * dy) / hypo
    Shoot.physicsBody?.velocity = CGVector(dx:newX, dy: newY)

}

}

【讨论】:

  • 请考虑解释这个答案如何解决原始问题中的问题。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2022-06-13
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-15
相关资源
最近更新 更多