-1

投稿するコードの量について事前に申し訳ありませんが、衝突検出を機能させることができないようです。テストをプレイすると、プレーヤーとオブジェクトは互いに影響を与えずに通過します。

警告やエラーは表示されませんが、Player の playerBot オブジェクトは、GLEED2D からインポートしたレベル アイテムと相互作用しているようには見えません。

私がしたことの1つは、アイテムの長方形と色配列の値をリストに保存して、それらをすべて簡単に反復できるようにすることでした.これが問題の原因かもしれません.

私のコードが機能しない理由を見つけることができれば、私は非常に感謝しています. 明らかに関係のないコードはすべて削除しました。役立つ場合は、GLEED2D 1.3 で VS 2010 を実行しています。

再度、感謝します。

// Item Class ImageItem Downcast
public class ImageItem : Item
{
    public Texture2D Texture;
}

// Level
Level level;

// Ints
int iNumOfItems = 0;
int iTextureDataListNum = 0;
int iRectangleListNum = 0;

// Lists
List<Color []> itemTextureDataList = new List<Color[]>();
List<Rectangle> itemRectangleList = new List<Rectangle>();

protected override void Initialize()
{
    if (filename.Length > 0) level = Level.FromFile(filename, Content);
    else level = Level.FromFile("level1.xml", Content);

    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {
            iNumOfItems =+ 1;
        }
    }

    // Creates Player Ship
    playerBot = new Player(new Vector2(400f, 240f), new Vector2(0f, 0f));

    base.Initialize();
}

protected override void LoadContent()
{
    Texture2D pixel = new Texture2D(GraphicsDevice, 1, 1, false, SurfaceFormat.Color);
    pixel.SetData(new[] { Color.White });
    spriteBatch = new SpriteBatch(GraphicsDevice);

    // Player Bot
    playerBot.LoadContent(Content, "Images/Player Bot Sprite Sheet", 40, 40, 4);

    // Assigns level textures color data to array
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {
            ImageItem imageItem = item as ImageItem;
            if (imageItem != null)
            {
                Texture2D texture = imageItem.Texture;

                itemTextureDataList[iTextureDataListNum] = new Color[imageItem.Texture.Width * imageItem.Texture.Height];
                imageItem.Texture.GetData(itemTextureDataList[iTextureDataListNum]);
                iTextureDataListNum++;
            }
        }
    }

    // Creates a rectangle for every level texture
    foreach (Layer layer in level.Layers)
    {
        foreach (Item item in layer.Items)
        {   
            ImageItem imageItem = item as ImageItem;
            if (imageItem != null)
            {
                itemRectangleList[iRectangleListNum] = new Rectangle((int)imageItem.Position.X, (int)imageItem.Position.Y, imageItem.Texture.Width, imageItem.Texture.Height);
                iRectangleListNum++;
            }
        }
    }

    spriteBatch = new SpriteBatch(GraphicsDevice);
}

protected override void Update(GameTime gameTime)
{
    // Player Update
    playerBot.Update(gameTime);
    ((Sprite)playerBot).Update(gameTime);

    // Check for player collisons with level
    for (int i = 0; i < iNumOfItems - 1; i++)
    {
        if (IntersectPixels(playerBot.colRectangle, playerBot.textureDataArray, itemRectangleList[i], itemTextureDataList[i]) == true)
        {
            playerBot.StopMovement();
        }
    }

    base.Update(gameTime);
}

// Level Collision Detection Method

static bool IntersectPixels(Rectangle rectangleA, Color[] dataA, Rectangle rectangleB, Color[] dataB)
{
    // Find the bounds of the rectangle intersection
    int top = Math.Max(rectangleA.Top, rectangleB.Top);
    int bottom = Math.Min(rectangleA.Bottom, rectangleB.Bottom);
    int left = Math.Max(rectangleA.Left, rectangleB.Left);
    int right = Math.Min(rectangleA.Right, rectangleB.Right);

    // Check every point within the intersection bounds
    for (int y = top; y < bottom; y++)
    {
        for (int x = left; x < right; x++)
        {
            // Get the color of both pixels at this point
            Color colorA = dataA[(x - rectangleA.Left) + (y - rectangleA.Top) * rectangleA.Width];
            Color colorB = dataB[(x - rectangleB.Left) + (y - rectangleB.Top) * rectangleB.Width];

            // If both pixels are not completely transparent
            if (colorA.A != 0 && colorB.A != 0)
            {
                // Then an intersection has been found
                return true;
            }
        }
    }

    // No intersection fond
    return false;
}

// スプライト クラス

public void Update(GameTime gameTime)
{
    textureDataArray = new Color[texture.Width * texture.Height];
    texture.GetData(textureDataArray);

// プレイヤー クラス

public void StopMovement()
{
    velocity.X *= -1;
    velocity.Y *= -1;
}
4

1 に答える 1

1

ここで私が最初に言うことは、アプローチにおいてよりオブジェクト指向になることを目指すべきだということです。テクスチャのリストと長方形のリストをアイテムのリストと一緒に保存するのは「悪い」テクニックであり、デバッグに関しては最終的に大きな頭痛の種になります。

まず、Color[] のリストと Rectangle のリストを持つ代わりに、1 つの Color[] と 1 つの Rectangle を ImageItem クラスに追加して、代わりにそれらを操作するか、少なくとも「CollisionData」という小さなクラスを作成します。 Rectangle と Color[] を持ち、それらを 1 つのリストに格納します。

次に、交差する長方形を取得する Rectangle.Intersect(Rectangle A, Rectangle B) があることに注意してください。したがって、それを使用してコードを少し整理できます。

カラーチェックは (ColorA.A * ColorB.A != 0) に単純化できます。いずれかがゼロになると結果がゼロになるからです。

エラーが発生しないようにするには、衝突チェック ループの開始点にブレークポイントを設定します。アプリケーションが壊れますか?はいの場合、iNumItems の値は? (カーソルを合わせると、ブレークポイントでの現在の値が表示されます)。いいえの場合、コードのそのセクションに到達していません。別のブレークポイントを少し後ろに置き、ヒットするまで少し後ろに置き、コードが実行されない理由を突き止めます。

于 2013-08-24T17:48:33.527 に答える