【问题标题】:SpriteKit - Push sprite away from touch locationSpriteKit - 将精灵推离触摸位置
【发布时间】:2014-06-08 23:56:29
【问题描述】:

我正在构建一个游戏,并希望我的一个精灵直接从玩家点击的地方移开。

                 [+] (tap location)

   [+] (player)

在上面的例子中,玩家会向左和向下移动。

谁能在物理方面帮助我?

我意识到我将使用三角函数来计算角度和向量(对于applyImpulse:),但我的计算不适用于玩家周围的每个象限。

这是我的代码(touchesBegan:

UITouch *touch = [touches.allObjects objectAtIndex:0];
CGPoint touchPosition = [touch locationInNode:self];
CGPoint playerPosition = self.playerBubble.position;

double oppositeLength = (touchPosition.y - playerPosition.y);
double adjacentLength = (touchPosition.x - playerPosition.x);
double angle = atan(oppositeLength / adjacentLength);

向量计算如下:

CGFloat playerMass = 0.0000013;

CGVector vector = CGVectorMake(playerMass * cosl(angle), playerMass * sinl(angle));

以下是玩家周围每个象限的矢量输出:

+、+

O: 133.000000, A: 42.500000, Angle: 72.278778, Theta: 1.261503
{3.9570166773706921e-07, 1.2383134543301224e-06}

-、+

O: 95.247955, A: -79.580551, Angle: -50.120930, Theta: -0.874775
{8.335201515172361e-07, -9.9761925504652419e-07}

+、-

O: -145.927795, A: 52.148361, Angle: -70.335281, Theta: -1.227582
{4.3747011829674742e-07, -1.2241813250586403e-06}

-、-

O: -138.968933, A: -92.015755, Angle: 56.490189, Theta: 0.985940
{7.1770369806877642e-07, 1.0839286982100348e-06}

编辑:

这是我的更新答案,它给出了正确的向量(在 SKSpriteNode 实例上调用):

- (void)moveWithTouchPosition:(CGPoint)touchPosition
{
    double heightLength = (self.position.y - touchPosition.y);
    double widthLength = (self.position.x - touchPosition.x);
    double angle = 0.0f;

    if (touchPosition.y > self.position.y && touchPosition.x > self.position.x) {
        //
        //  +, +
        //
        angle = M_PI + atan(heightLength / widthLength);
    } else if (touchPosition.y > self.position.y && touchPosition.x < self.position.x) {
        //
        //  -, +
        //
        angle = M_PI + M_PI_2 + atan(widthLength / heightLength);
    } else if (touchPosition.y < self.position.y && touchPosition.x > self.position.x) {
        //
        //  +, -
        //
        angle = M_PI_2 + atan(widthLength / heightLength);
    } else if (touchPosition.y < self.position.y && touchPosition.x < self.position.x) {
        //
        //  -, -
        //
        angle = atan(heightLength / widthLength);
    }

    CGVector vector = CGVectorMake(self.physicsBody.mass * cosl(angle), self.physicsBody.mass * sinl(angle));
    [self.physicsBody applyImpulse:vector];
}

【问题讨论】:

    标签: ios sprite-kit


    【解决方案1】:

    为了简化您的代码,您可以使用 atan2 代替 atan。 Atan2 为您做象限。

    另一种选择是转换和相乘向量,而不是使用三角函数,这可能看起来像:

    CGVector vector = CGVectorMake(
        (playerPosition.x - touchPosition.x) * playerMass + touchPosition.x, 
        (playerPosition.y - touchPosition.y) * playerMass + touchPosition.y
    );
    

    【讨论】:

    • 刚刚用看似有效的向量编辑了我的答案。不过,似乎没有必要使用 if。我在一张备用纸上画了很多图表,但似乎这是唯一的方法。不知道有没有更简单的方法?谢谢
    • 如果你想使用atan,你看过atan2吗?它会为您完成象限的工作。
    • 真的吗?!这既烦人又难以置信的消息哈哈,我是不是只把相反和相邻的两个参数解析为两个参数?
    • 好的,所以刚刚在 Apple 文档中进行了研究。它似乎做到了!非常感谢! :)
    【解决方案2】:

    感谢@Bemmu,看来我真正需要做的就是使用 atan2(y, x) 函数并解析三角形的 Opp 和 Adj 长度,它们分别是 y 和 x 值之间的差异。

    例如:

    double heightLength = (self.position.y - touchPosition.y);
    double widthLength = (self.position.x - touchPosition.x);
    double angle = atan2(heightLength, widthLength);
    
    CGFloat acceleration = 100.0f;
    
    CGVector vector = CGVectorMake(self.physicsBody.mass * (cosl(angle) * acceleration), self.physicsBody.mass * (sinl(angle) * acceleration));
    [self.physicsBody applyImpulse:vector];
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2019-04-12
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多