如何检测与地图的碰撞?我想检测一下我的地图和汽车的碰撞。扫描颜色。
在我的底图上:轨道是灰色的,草是白色的,墙壁是黄色的。
在我的上图:轨道更真实,这是他们所看到的。
我尝试了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();
}
答案 0 :(得分:1)
答案 1 :(得分:1)
我不建议像素碰撞,因为它是不必要的CPU和FPS杀手。 这里有一些可以帮助你的collsions。但是如果你真的需要像素碰撞,首先检查矩形或任何其他碰撞检测,然后如果相交,那么使用像素collsion是非常的...但我不建议这样做,特别是在快速游戏中。
这里有一些可以帮助你的碰撞功能
POLYGON
http://www.codeproject.com/Articles/15573/2D-Polygon-Collision-Detection
CIRCLE:
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));
}