2

弾丸を発射する船を回転させたときに弾丸の位置を更新すると、問題が発生します。現在、ほとんどの角度で弾丸が希望する場所から発射されないことを除いて、コードはほとんど機能します。本来あるべき中心より少し上向きに発射されることもあれば、下向きに発射されることもあります。三角法と関係があると確信していますが、問題を見つけるのに苦労しています。

このコードはコンストラクターにあります。sp.position船の位置 ( ) とその回転 ( Controls.rotation)に基づいて、弾丸の初期位置と回転を設定します。

this.backgroundRect = new RotatedRectangle(Rectangle.Empty, Controls.rotation);
//get centre of ship
this.position = new Vector2(sp.getPosition().X + sp.getTexture().Width/2, 
(sp.getPosition().Y + sp.getTexture().Height / 2));

//get blast pos
this.position = new Vector2((float)(this.position.X + (sp.getTexture().Width / 2 * 
Math.Cos(this.backgroundRect.Rotation))), (float)(this.position.Y + 
(sp.getTexture().Width / 2 * Math.Sin(this.backgroundRect.Rotation))));

//get blast pos + texture height / 2
this.position = new Vector2((float)(this.position.X + (this.texture.Height / 2 * 
Math.Cos(this.backgroundRect.Rotation))), (float)(this.position.Y + 
(this.texture.Height / 2 * Math.Sin(this.backgroundRect.Rotation))));
        
this.backgroundRect = new RotatedRectangle(new Rectangle((int)this.position.X, 
(int)this.position.Y, this.texture.Width, this.texture.Height), Controls.rotation);
speed = defSpeed;

次に、更新メソッドで次のコードを使用します。私はこれがうまくいっていると確信しています:

this.position.X = this.position.X + defSpeed * 
(float)Math.Cos(this.getRectangle().Rotation);
this.position.Y = this.position.Y + defSpeed * 
(float)Math.Sin(this.getRectangle().Rotation);
this.getRectangle().CollisionRectangle.X = (int)(position.X + defSpeed * 
(float)Math.Cos(this.getRectangle().Rotation));
this.getRectangle().CollisionRectangle.Y = (int)(position.Y + defSpeed * 
(float)Math.Sin(this.getRectangle().Rotation));
    

また、原点 (回転の中心) が (0,0) だったので、船を回転させたときに船が正しく機能していなかったことにも言及する必要があります。これを改善するために、原点を船の中心 (幅/2、高さ/2) に変更し、それらの値を描画長方形に追加して、スプライトが正しく描画されるようにしました。これが問題である可能性があり、これを回避するより良い方法があると思います。ちなみにゲームは2Dです。

4

1 に答える 1

1

問題は、スプライトが本来あるべき位置に描画されないことです。中心位置を計算するときは、スプライトが回転していないと仮定します。これにより、いくつかの問題が発生します。さらに、任意のベクトルを回転させることは、あなたがしたほど簡単ではありません。ベクトルが x 軸上にある場合、そのコンポーネントに sin/cos を掛けることによってのみ、ベクトルを回転させることができます。

任意のベクトルを回転させる方法は次のとおりです。

Vector2 vecRotate(Vector2 vec, double phi)
{
    double length = vec.Length(); //Save length of vector
    vec.Normalize();
    double alpha = Math.Acos(vec.X); //Angle of vector against x-axis
    if(vec.Y < 0)
        alpha = 2 * Math.PI - alpha
    alpha += phi;
    vec.X = Math.Cos(alpha) * length;
    vec.Y = Math.Sin(alpha) * length;
    return vec;
}

角度がラジアンであることを確認してください。これにより、船の正しい位置を計算できます。

Vector2 ShipCenter = sp.Position() + vecRotate(new Vector2(sp.getTexture().Width/2, sp.getTexture().Height/2), Controls.Rotation);

同じ関数を使用して、弾丸の中心の位置を決定できます。弾丸をどこに配置したいのか正確にはわかりません。右端の中央にあると仮定します。

Vector2 offset = new Vector2(sp.getTexture.Width/2, 0);
this.position = ShipCenter + vecRotate(offset, Controls.Rotation);

次に、箇条書きの左上隅の位置が必要な場合は、さらに進むことができます。

this.position -= vecRotate(new Vector2(this.texture.Width/2, this.texture.Height/2), Controls.Rotation)

ただ、先にも述べたように、船と弾丸の位置は中心位置として扱いやすいのではないでしょうか。そうすることで、必要な三角法がはるかに少なくなります。

于 2012-04-17T07:54:19.583 に答える