计算两个SKSpriteNodes之间的拦截速度

时间:2016-11-01 17:07:15

标签: objective-c sprite-kit game-physics

我创建了一个“ship”节点,沿着圆形路径移动,如下所示:

self.orbit = [OrbitManager getCirclePathWithCenter:centerRealPt radius:radius startingAngle:angelFromCenter isClockwise:self.isClockwise];

SKAction* orbitAction = [SKAction followPath:self.orbit asOffset:NO orientToPath:YES speed:300];

[self.ship.node runAction:orbitAction];

我有一门大炮,通过对它施加速度射击子弹,如下:

bullet.node.physicsBody.velocity = [ActionHelper getVelocityFrom:bullet.node toNodeB:self.target speed:bullet.speed];

当船沿着路径移动时。但子弹每次都会错过。如何以给定的速度计算大炮应该瞄准的位置?

2 个答案:

答案 0 :(得分:1)

这是我的Objective-C(它实际上是一个C函数)将射弹射入移动目标的解决方案。

您可以查看派生In this SO topic

这会给你一个生命值和射击角度, 您可以简单地将其转换为速度,因为您知道角度和抛射速度,它将类似于:

`CGVector Velocity = CGVectorMake(speed * cos(theta), speed * sin(theta));`


BOOL calculateAngleToShoot(CGVector targetVelocity, CGPoint targetPosition, CGPoint selfPos,CGFloat projectileSpeed,CGFloat *theta, CGPoint * hitPoint)
{
    CGFloat dx = targetPosition.x - selfPos.x;
    CGFloat dy = targetPosition.y - selfPos.y;

    CGVector v = targetVelocity;

    CGFloat a = v.dx * v.dx + v.dy * v.dy - projectileSpeed * projectileSpeed;
    CGFloat b = 2 * (v.dx * dx + v.dy * dy);
    CGFloat c = v.dx * v.dx + v.dy * v.dy;

    CGFloat q = b * b - 4 *  a * c;
    if (q < 0)
    {
        //Dead End;
        return NO;
    }
    CGFloat t = ((a < 0 ? -1 : 1) * sqrt(q) - b) / (2 * a);

    // Aim for where the target will be after time t
    dx += t * v.dx;
    dy += t * v.dy;
    *theta = atan2(dy, dx);

    *hitPoint = CGPointMake(targetPosition.x + v.dx * t, targetPosition.y + v.dy * t);
    return YES;
}

答案 1 :(得分:1)

经过一番调查后,我得到了如何得到答案

首先我需要获得目标和中心之间的距离(d) 以及子弹从中心到目标的时间。 由于船沿着圆移动,所以半径也等于距离(d)

CGFloat timeToArriveTarget = bullet.speed/distance;
CGFloat angularSpeed = bullet.speed/distance;

找出在这段时间内移动的角度

CGFloat angle = angularSpeed * timeToArriveTarget;

CGFloat x = self.target.position.x;
CGFloat y = self.target.position.y;
CGFloat a = bullet.node.position.x;
CGFloat b = bullet.node.position.y;

最后使用这个公式: 详情请参阅此链接https://math.stackexchange.com/a/266837

CGPoint targetPt = CGPointMake((x - a) * cos(angle) - (y - b) * sin(angle) + a, (x - a) * sin(angle) + (y - b) * cos(angle) + b);

bullet.node.physicsBody.velocity = [ActionHelper getVelocityFrom:bullet.node.position toPtB:targetPt speed:bullet.speed];

getVelocity函数由

给出
+(CGVector)getVelocityFrom:(CGPoint)ptA toPtB:(CGPoint)ptB speed:(CGFloat)speed{

CGPoint targetPosition = ptB;
CGPoint currentPosition = ptA;

double angle = [MathHelper getRotateAngleFrom:currentPosition toTargetPosition:targetPosition];
double velocityX = speed * cos(angle);
double velocityY = speed * sin(angle);

CGVector newVelocty = CGVectorMake(velocityX, velocityY);
return newVelocty;

}