0

私は過去2日間、弓から発射された矢の動きを理解するのに費やしましたが、完璧な最終結果は得られませんでした。これが私がこれまでに持っているものです:

    - (void) update:(ccTime) dt {
    elapsedTime += dt;
    CGFloat t = elapsedTime;
    float theta = CC_DEGREES_TO_RADIANS(angle);
    velocity = ccp (initialVelocity.x* cos(theta), initialVelocity.y*sin(theta));


    float k = 0.3; //this would be the air resistance factor
    float vvx = sqrtf( velocity.x*velocity.x + velocity.y*velocity.y );
    float vvy = sqrtf( velocity.x*velocity.x + velocity.y*velocity.y );

    CGFloat ax = -k*vvx; //accelerationX
    CGFloat ay = -k*vvy - gravity; //accelerationY


    velocity = ccp(velocity.x + ax * t , velocity.y + ay * t);

    CGPoint oldPosition = self.position;
    CGPoint newPosition = ccp(self.position.x + velocity.x * t + ax * t * t, self.position.y + velocity.y * t + ay * t * t);

    CGPoint v1 = CGPointMake(0.0, 0.0);
    CGPoint v2 = CGPointMake(newPosition.x - oldPosition.x ,  newPosition.y - oldPosition.y);
   CGFloat newAngle = (atan2(v2.y, v2.x) - atan2(v1.y, v1.x));
    self.rotation = CC_RADIANS_TO_DEGREES(-newAngle);
    self.position = newPosition;

}

このコードを使用すると、次の動作が得られます。

使用:k =0.3および角度=0度、重力= 9.8

initialVelocity = 100の場合、矢印には放物線軌道があります。

initialVelocity = 200の場合、矢印はより速く移動しますが、initialVelocity=100の場合とまったく同じ軌道になります。

initialVelocity = 300の場合、矢印ははるかに速く移動し、軌道はわずかに異なりますが、それでもinitialVelocity=100の軌道に非常に近くなります。

私のコードに何か問題がありますか?私はすべての概念をよく理解しているわけではないことに注意してください。実装の多くは、私がオンラインで読んだものに基づくヒット&ミスです。

4

2 に答える 2

1

You're adding in acceleration multiple times. You have:

velocity = ccp(velocity.x + ax * t , velocity.y + ay * t);

and then below that:

CGPoint newPosition = ccp(self.position.x + velocity.x * t + ax * t * t, self.position.y + velocity.y * t + ay * t * t);

It looks to me like you could simplify that second line to just

CGPoint newPosition = ccp(self.position.x + velocity.x * t, self.position.y + velocity.y * t);

However, I think your overall algorithm is more complicated than it needs to be, and that makes bugs harder to find. There shouldn't be any reason to track angle; just separate the vectors and handle each independently. In pseudocode, something like this:

// setup
vx = cos(InitAngle) * InitVelocity;
vy = sin(InitAngle) * InitVelocity;
locx = 0;
locy = 0;
gravity = -1.0;
friction  -0.01;

// loop
Update(t) {
  vx *= 1+(friction * t);
  vy +=gravity * t;
  locx += vx * t;
  locy += vy * t;
}

(I may have the sin/cos reversed; I always get that wrong.)

于 2012-11-01T15:20:45.363 に答える
0

Horatiu、物理的なエンジンを使用せず、ヒット&ミスを使用したい場合は、空気抵抗なしで開始することをお勧めします。簡単に始めて、簡単な物理学から助けを集めてください:投げられた物体の方程式(加速度、速度、位置、導関数、時間)そしてそれがうまくいったら、空気摩擦を加えます。正しい方程式が得られたら、コーディングは簡単なステップになります。

于 2012-11-01T14:51:09.167 に答える