1

過去12時間、XNA(4.0)で2つの長方形を正しく交差/テスト衝突させるために、考えられる「すべての」さまざまな方法を試してきました。

私には3つのクラスがあります(名前の例だけです):

  • Game1.cs
  • Player.cs
  • Man.cs

Game1では、次のようにコンテンツをロードします。

// Game1の開始時:

    Player player;
    Man man;

// LoadContent:

    man = new Man(Content.Load<Texture2D>("ManImage"), new Rectangle(440, 310, 150, 98));
    player = new Player(Content.Load<Texture2D>("playerSheet"), new Vector2(40, 420), 50, 44);

ただし、人とプレイヤーの衝突をチェックしたいのですが、Game1でif(intersects)を実行できるようにするためにこれら2つのクラスを「結合」する方法がわかりません(それを実行する場所である場合)。

プレーヤーの長方形は次のようになります。

playerRect = new Rectangle(currentFrame * frameWidth, 0, frameWidth, frameHeight);

ここで完全に「コードブラインド」になったのでしょうか。これを手伝ってくれる人は誰でも、12時間の衝突テストの後でモチベーションが低下しました。

4

1 に答える 1

1

両方のクラスについて、プロパティを追加できます

public Rectangle PositionRectangle { get; private set; }

次に、関連するコンストラクターで、このプロパティを開始する必要があります

public Man(..., Rectangle rectangle)
{
    PositionRectangle = rectangle;
}

public Player(..., Vector2 position, int width, int height)
{
    PositionRectangle = new rectangle((int)position.X, (int)position.Y, width, height);
}

表示しているフレームについて心配する必要はありません。これは、宛先の長方形(衝突をテストするために必要なもの)ではなく、ソースの長方形に関連しているためです。

次に、これらの衝突を簡単にテストできます

if(man.PositionRectangle.Intersects(player.PositionRectangle))
{
    //collision logic
}

もちろん、位置(または変更可能な場合は幅と高さ)を変更するたびに、これらの長方形を更新するように注意する必要があります。


わずかな編集(またはより良いバージョン)

長方形がどのように更新されるかを気にせずに、ManとPlayerを簡単に配置したい場合は、次のように設定できます。

class Man
{
    Texture2D _texture;

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Man(Texture2D texture)
    {
        this._texture = texture;
        this.Width = texture.Width;
        this.Height = texture.Height;
    }

    ... //other man related logic!
}

class Player
{
    Texture2D _texture;
    int _frameCount;
    int _currentFrame;
    //other frame related logic...

    public Vector2 Position { get; set; }
    public int Width { get; set; } 
    public int Height { get; set; }

    public Rectangle PositionRectangle
    {
        get
        {
            return new Rectangle((int)Position.X, (int)Position.Y, Width, Height);
        }
    }

    public Rectangle SourceRectangle
    {
        get
        {
            return new Rectangle(Width * _currentFrame, 0, Width, Height);
        }
    }

    public Player(Texture2D texture, int frameWidth, int frameCount)
    {
        this._texture = texture;
        this.Width = frameWidth;
        this.Height = texture.Height;
        this._frameCount = frameCount;
        this._currentFrame = 0;
        //etc...
    }

    ... //other player related logic! such as updating _currentFrame

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, SourceRectangle, Color.White);
    }
}

ここでは、プロパティアクセサーを使用して、関連する長方形を動的に生成する方法の例を示しました。

PositionRectangleプレーヤー(または男性)が画面上のどこに配置されるかを決定するために使用しSourceRectangle、テクスチャのどの部分を描画するかを決定するために使用します。

また、男性とプレーヤーの幅と高さが変わらない場合は、setアクセサーをに設定する必要がありますprivate

場所を変更する必要がある場合は、位置プロパティを設定するだけです

man.Position = new Vector2(100, 100); //i.e.

衝突と描画ロジックは、それ以上の介入なしに新しい長方形を自動的に使用します。

あなたがそれを好きになることを願っています!

Edit2

ソース長方形が公開されていることに関連して、これらを外部から描画している場合(つまりGame1呼び出しspriteBatch.Draw(player.Texture, player.PositionRectangle, player.SourceRectangle, Color.White);)にのみ必要です。

例のように(内側から)描画している場合は、すべてをスクラップして、public Recangle SourceRectangle{...}その長方形を直接描画に使用できます。

    public Draw(SpriteBatch spriteBatch)
    {
         spriteBatch.Draw(_texture, PositionRectangle, new Rectangle(Width * _currentFrame, 0, Width, Height), Color.White);
    }
于 2012-04-29T10:29:46.413 に答える