0

発射体の動きのあるボールを投げたいです。画面の中央にサルがいて、onTouchBegin はタッチの始点を、onTouchEnded は終点をとっています。始点と終点から、それらの間の角度値を取得しています。30度とか45度とか90度とか。これは、始点から終点までの角度を計算した私のコードです

    float angleRadians = atan2(startTouchPoint.x - touchPoint.x, startTouchPoint.y -    touchPoint.y);
    float angleDegrees = CC_RADIANS_TO_DEGREES(angleRadians);
    float cocosAngle = -1 * angleDegrees;

今、私は上記の式から計算した角度で​​ボールを投げるために発射体運動式を使用しています。

内部初期化メソッド

        gravity = 9.8; // metres per second square
        X = 0;
        Y = 0;
        V0 = 50; // meters per second -- elevation
        VX0 = V0 * cos(angle); // meters per second
        VY0 = V0 * sin(angle); // meters per second
        gameTime = 0;

と onTouchEnded 私はボールを投げる fire メソッドを呼び出しました

-(void)fire:(ccTime) dt
{

    CCLOG(@"Angle 1: %.2f",angle);
    gameTime += dt*6;

    // x = v0 * t * cos(angle)
    X = (V0 * gameTime * cos(angle))/2+120;

    // y = v0 * t * sin(angle) - 0.5 * g * t^2
    Y = (V0 * gameTime * sin(angle) - 0.5 * gravity * pow(gameTime, 2))/2+255;

    if (Y > 50)

    {
        sprite_webfire.position = ccp(X,Y);
        flag = true;
    }

    else
    {

        //angleValue += 15;
        angleValue = angle;
        angle = [self DegreesToRadians:angleValue];
        gravity = 9.8; // metres per second square
        X = 0;
        Y = 0;
        V0 = 50; // meters per second -- elevation
        VX0 = V0 * cos(angle); // meters per second
        VY0 = V0 * sin(angle); // meters per second
        gameTime = 0;

        // [self pauseSchedulerAndActions];
    }

    if (Y < 50)

    {
        [self unschedule:@selector(fire:)];        
    }

    NSLog(@"ball (%lf,%lf), dt = %lf angle value %d", X, Y, dt,angleValue);
}

このコードは機能しています。このコードにより、発射体の動きでボールを投げることができますが、好きな場所に投げることができません。開始点から終了点まで、指定された角度に wrt を投げることはできません。

赤いマークのように投げることができますが、スワイプで青いマークを投げたいです。しかし、画面をスワイプしているように投げません。

ここに画像の説明を入力

4

2 に答える 2

1

これを行うために使用している数学についてはわかりません。ドキュメントが少しわかりにくいと思います。

通常、プロジェクト タイルのモーションでは、次のことを行う必要があります。

水平線に対する離陸角度を調べます。次に、オブジェクトに持たせたい初期速度に応じて、それを使用し、方程式をトリガーして、初期速度を長方形のコンポーネントに入れます。

例えば:

初速度が 10 の場合、y 方向の初速度は 10sin(角度)、x 方向の初速度は 10cos(角度) になります。

次に、スプ​​ライトの位置を更新するには、運動方程式を使用する必要があります: http://www.physicsclassroom.com/class/1dkin/u1l6c.cfm

最初の更新速度:

Y 方向の速度: V = v(初期値) + 重力*(デルタ時間)

X 方向の速度は、物事をより複雑にするために何らかの抵抗を考慮に入れたい場合を除き、一定です。

位置 y = oldPositionY + 速度 (Y 方向)*(デルタ時間) + 1/2(重力)(デルタ時間)^2.

位置 x = oldPositionX + Xvelocity*delta-time

私はいくつかの発射体の動きを行いましたが、重力を大きな定数にする必要があることを発見しました.500程度にすると、生きているように見えます. これが紛らわしい場合、または実装方法がわからない場合はお知らせください。

次のチュートリアルをご覧になることをお勧めします: http://www.raywenderlich.com/4756/how-to-make-a-catapult-shooting-game-with-cocos2d-and-box2d-part-1 .

物理エンジンの使用方法を示しているため、多くの計算を行う必要はありません。チュートリアルのすべての「弾丸」も発射体の動きで動いています。

于 2013-01-04T23:45:15.763 に答える
0

すでに述べたことに少し追加します(これは良かったです)。まず、角度の計算に時間を無駄にすべきではありません。速度のベクトルに固執します。つまり、タッチの開始位置と終了位置から初速度ベクトルを取得すると、それが (v0x, v0y) になります。例えば:

CGPoint initialVelocity = ccpSub(touchPoint, startTouchPoint);
float v0x = initialVelocity.x;
float v0y = initialVelocity.y;

初期速度ベクトルに異なるマグニチュードを割り当てたい場合は、単純に正規化してから、新しいマグニチュードを掛けます。

CGPoint unitVelocity = ccpNormalize(initialVelocity);
float magnitude = 200; // or whatever you want it to be
CGPoint velocity = ccpMult(unitVelocity, magnitude);

とにかく、この速度を適切に設定すると、以前と同じように位置計算に使用できますが、角度を計算する複雑さが増すことはありません。

-(void) fire:(ccTime)dt
{
    .
    .
     gameTime += dt;
     // if x(t) = x0 + v0x*t, then dx = v0x*dt
     x += v0x*dt;

     // if y(t) = y0 + v0y*t - 0.5t^2, then dy = v0y*dt - g*t*dt
     y += (v0y * dt - g*gameTime*dt);
     .
     .
}

また、設定しないでくださいv0 = 50。私が提案したように、ベクトルから速度を計算します。

考慮すべき重要なことは、メートルの単位に基づいて、物理的な世界での動きがどうあるべきかを計算していることです。画面はメートル単位ではなくポイント単位で動作するため、目的の外観を得るには、おそらく新しい位置 (x、y) に倍率を適用する必要があります。

編集:悪いことに、位置計算で数学を再検討する必要がありました。私のデフは少し錆びていました。

于 2013-01-05T10:22:25.423 に答える