0

如何检测与我的地图的碰撞?我想检测与我的地图和汽车的碰撞。扫描颜色。

在我的底图上:轨道是灰色的,草是白色的,墙壁是黄色的。

在我的上图:赛道更真实,这是他们所看到的。

我尝试了http://www.xnadevelopment.com/tutorials/theroadnottaken/theroadnottaken.shtml但是当我遇到碰撞时,代码不起作用。其中很多在 XNA 4.0 中不起作用,但它正是我可以使用的。

//This method checks to see if the Sprite is going to move into an area that does
//not contain all Gray pixels. If the move amount would cause a movement into a non-gray
//pixel, then a collision has occurred.
private bool CollisionOccurred(int aMove)
{

    //Calculate the Position of the Car and create the collision Texture. This texture will contain
    //all of the pixels that are directly underneath the sprite currently on the Track image.
    float aXPosition = (float)(-mCarWidth / 2 + mCarPosition.X + aMove * Math.Cos(mCarRotation));
    float aYPosition = (float)(-mCarHeight / 2 + mCarPosition.Y + aMove * Math.Sin(mCarRotation));
    Texture2D aCollisionCheck = CreateCollisionTexture(aXPosition, aYPosition);

    //Use GetData to fill in an array with all of the Colors of the Pixels in the area of the Collision Texture
    int aPixels = mCarWidth * mCarHeight;
    Color[] myColors = new Color[aPixels];
    aCollisionCheck.GetData<Color>(0, new Rectangle((int)(aCollisionCheck.Width / 2 - mCarWidth / 2), (int)(aCollisionCheck.Height / 2 - mCarHeight / 2), mCarWidth, mCarHeight), myColors, 0, aPixels);

    //Cycle through all of the colors in the Array and see if any of them
    //are not Gray. If one of them isn't Gray, then the Car is heading off the road
    //and a Collision has occurred
    bool aCollision = false;
    foreach (Color aColor in myColors)
    {
        //If one of the pixels in that area is not Gray, then the sprite is moving
        //off the allowed movement area
        if (aColor != Color.Gray)
        {
            aCollision = true;
            break;
        }
    }
    return aCollision;
}

第2部分

//Create the Collision Texture that contains the rotated Track image for determing
//the pixels beneath the Car srite.
private Texture2D CreateCollisionTexture(float theXPosition, float theYPosition)
{
    //Grab a square of the Track image that is around the Car
    graphics.GraphicsDevice.SetRenderTarget(0, mTrackRender);
    graphics.GraphicsDevice.Clear(ClearOptions.Target, Color.Red, 0, 0);

    mSpriteBatch.Begin();
    mSpriteBatch.Draw(mTrack, new Rectangle(0, 0, mCarWidth + 100, mCarHeight + 100), 
        new Rectangle((int)(theXPosition - 50), 
        (int)(theYPosition - 50), mCarWidth + 100, mCarHeight + 100), Color.White);
    mSpriteBatch.End();

    graphics.GraphicsDevice.ResolveRenderTarget(0);
    graphics.GraphicsDevice.SetRenderTarget(0, null);

    Texture2D aPicture = mTrackRender.GetTexture();

    //Rotate the snapshot of the area Around the car sprite and return that 
    graphics.GraphicsDevice.SetRenderTarget(0, mTrackRenderRotated);
    graphics.GraphicsDevice.Clear(ClearOptions.Target, Color.Red, 0, 0);

    mSpriteBatch.Begin();
    mSpriteBatch.Draw(aPicture, new Rectangle((int)(aPicture.Width / 2), (int)(aPicture.Height / 2), 
        aPicture.Width, aPicture.Height), new Rectangle(0, 0, aPicture.Width, aPicture.Width), 
        Color.White, -mCarRotation, new Vector2((int)(aPicture.Width / 2), (int)(aPicture.Height / 2)), SpriteEffects.None, 0);
    mSpriteBatch.End();

    graphics.GraphicsDevice.ResolveRenderTarget(0);
    graphics.GraphicsDevice.SetRenderTarget(0, null);

    return mTrackRenderRotated.GetTexture();
}
4

2 回答 2

1

我不推荐像素碰撞,因为它是不必要的 CPU 和 FPS 杀手。这里有一些可以帮助你的碰撞。但是如果你真的需要像素碰撞,首先检查矩形或任何其他碰撞检测,然后如果相交然后使用像素碰撞来精确......但我不建议这样做,尤其是在快速游戏中。

这里有一些碰撞功能可以帮助你

多边形

http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection

圆圈:

int circlesColliding(int x1,int y1,int radius1,int x2,int y2,int radius2)
{
    //compare the distance to combined radii
    int dx = x2 - x1;
    int dy = y2 - y1;
    int radii = radius1 + radius2;
    if ( ( dx * dx )  + ( dy * dy ) < radii * radii ) 
    {
        return true;
    }
    else
    {
        return false;
    }
}

圆转长方形

bool intersects(CircleType circle, RectType rect)
{
    circleDistance.x = abs(circle.x - rect.x);
    circleDistance.y = abs(circle.y - rect.y);

    if (circleDistance.x > (rect.width/2 + circle.r)) { return false; }
    if (circleDistance.y > (rect.height/2 + circle.r)) { return false; }

    if (circleDistance.x <= (rect.width/2)) { return true; } 
    if (circleDistance.y <= (rect.height/2)) { return true; }

    cornerDistance_sq = (circleDistance.x - rect.width/2)^2 +
                         (circleDistance.y - rect.height/2)^2;

    return (cornerDistance_sq <= (circle.r^2));
}
于 2013-10-18T08:41:32.070 回答
1

我不确定如何解决您的特殊情况,但我只是推荐Riemers

我确信他的教程之一有颜色检测,我认为这是他的 2d 坦克游戏。

莫娜

于 2013-10-18T03:44:21.673 回答