/// <summary> /// Determines if there is overlap in the non-transparent pixels between two Color arrays. /// </summary> /// <param name="dataA">The first Color array.</param> /// <param name="destA">The destination rectangle for Color array A.</param> /// <param name="srcA">The source rectangle for Color array A.</param> /// <param name="srcA">The width of each line in Color array A.</param> /// <param name="dataB">The second Color array.</param> /// <param name="destB">The destination rectangle for Color array B.</param> /// <param name="srcB">The source rectangle for Color array B.</param> /// <param name="srcB">The width of each line in Color array B.</param> public static bool PerPixelIntersect(Color[] dataA, Rectangle destA, Rectangle srcA, int dataAWidth, Color[] dataB, Rectangle destB, Rectangle srcB, int dataBWidth) { if (destA.Intersects(destB)) { int top = Math.Max(destA.Top, destB.Top); int bottom = Math.Min(destA.Bottom, destB.Bottom); int left = Math.Max(destA.Left, destB.Left); int right = Math.Min(destA.Right, destB.Right); for (int y = top; y < bottom; y++) { for (int x = left; x < right; x++) { int xA = srcA.Left + (x - destA.Left); int yA = srcA.Top + (y - destA.Top); Color colorA = dataA[xA + (yA * dataAWidth)]; int xB = srcB.Left + (x - destB.Left); int yB = srcB.Top + (y - destB.Top); Color colorB = dataB[xB + (yB * dataBWidth)]; if (colorA.A != 0 && colorB.A != 0) return true; } } } return false; }
protected override void Draw(GameTime gameTime) { if (this.graphicsDevice.BeginDraw()) { this.graphicsDevice.Clear(Color.CornflowerBlue); this.effect.SetValue<float>("StartX", 100.0f); this.effect.SetValue<float>("Time", (float)gameTime.TotalTime.TotalSeconds); this.graphics.Begin(this.effect, 0, 0); int totalChunks = 100; int chunkSize = this.texture.Width / totalChunks; Rectangle destination = new Rectangle(100, 142, chunkSize, this.texture.Height); Rectangle source = new Rectangle(0, 0, chunkSize, this.texture.Height); for (int i = 0; i < totalChunks; i++) { this.graphics.DrawTexture(this.texture, destination, source, Color.White); destination.X += chunkSize; source.X += chunkSize; } this.graphics.End(); this.graphicsDevice.EndDraw(); this.graphicsDevice.Present(); } }
public void PerPixelIntersectWithSrc() { Rectangle destA = new Rectangle(0, 0, 4, 4); Rectangle srcA = new Rectangle(0, 0, 4, 4); Color[] dataA = CreateTwoFrameColorData(); Rectangle destB = new Rectangle(0, 0, 4, 4); Rectangle srcB = new Rectangle(4, 0, 4, 4); Color[] dataB = CreateTwoFrameColorData(); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, srcA, 8, dataB, destB, srcB, 8)); destB = new Rectangle(1, 1, 4, 4); Assert.IsFalse(CollisionHelper.PerPixelIntersect(dataA, destA, srcA, 8, dataB, destB, srcB, 8)); destB = new Rectangle(2, 1, 4, 4); Assert.IsFalse(CollisionHelper.PerPixelIntersect(dataA, destA, srcA, 8, dataB, destB, srcB, 8)); destB = new Rectangle(-1, -1, 4, 4); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, srcA, 8, dataB, destB, srcB, 8)); destB = new Rectangle(-1, 0, 4, 4); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, srcA, 8, dataB, destB, srcB, 8)); destB = new Rectangle(0, -1, 4, 4); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, srcA, 8, dataB, destB, srcB, 8)); }
/// <summary> /// Constructor. /// </summary> /// <param name="baseRectangle"></param> /// <param name="origin"></param> /// <param name="rotation"></param> public RotatableRectangle(Rectangle baseRectangle, Vector2 origin, float rotation) { this.BaseRectangle = baseRectangle; this.origin = origin; this.rotation = rotation; this.recalculateCorners = true; }
protected override void Draw(GameTime gameTime) { if (this.graphicsDevice.BeginDraw()) { this.graphicsDevice.Clear(Color.Black); this.graphics.Begin(); Vector2 oneThirdScreen = new Vector2((int)(this.graphicsDevice.BackBufferWidth / 3), (int)(this.graphicsDevice.BackBufferHeight / 3)); Rectangle oneThirdScreenRectangle = new Rectangle(0, 0, (int)oneThirdScreen.X, (int)oneThirdScreen.Y); for (int y = 0; y < 3; y++) { for (int x = 0; x < 3; x++) { oneThirdScreenRectangle.X = (int)oneThirdScreen.X * x; oneThirdScreenRectangle.Y = (int)oneThirdScreen.Y * y; this.graphics.DrawFilledRectangle(oneThirdScreenRectangle, new Color((byte)(80 * x), (byte)(80 * (x - y)), (byte)(80 * (3 - y)), 255)); } } this.graphics.DrawTextBlock(this.topLeftTextBlock, new Vector2(0, 0), Color.White); this.graphics.DrawTextBlock(this.topCenterTextBlock, new Vector2(oneThirdScreen.X, 0), Color.White); this.graphics.DrawTextBlock(this.topRightTextBlock, new Vector2(oneThirdScreen.X * 2, 0), Color.White); this.graphics.DrawTextBlock(this.middleLeftTextBlock, new Vector2(0, oneThirdScreen.Y), Color.White); this.graphics.DrawTextBlock(this.middleCenterTextBlock, new Vector2(oneThirdScreen.X, oneThirdScreen.Y), Color.White); this.graphics.DrawTextBlock(this.middleRightTextBlock, new Vector2(oneThirdScreen.X * 2, oneThirdScreen.Y), Color.White); this.graphics.DrawTextBlock(this.bottomLeftTextBlock, new Vector2(0, oneThirdScreen.Y * 2), Color.White); this.graphics.DrawTextBlock(this.bottomCenterTextBlock, new Vector2(oneThirdScreen.X, oneThirdScreen.Y * 2), Color.White); this.graphics.DrawTextBlock(this.bottomRightTextBlock, new Vector2(oneThirdScreen.X * 2, oneThirdScreen.Y * 2), Color.White); this.graphics.End(); this.graphicsDevice.EndDraw(); this.graphicsDevice.Present(); } }
public void PerPixelIntersectWithoutSrc() { Rectangle destA = new Rectangle(0, 0, 4, 4); Color[] dataA = CreateOneFrameColorData(); Rectangle destB = new Rectangle(0, 0, 4, 4); Color[] dataB = CreateOneFrameColorData(); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, dataB, destB)); destB = new Rectangle(0, 1, 4, 4); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, dataB, destB)); destB = new Rectangle(1, 1, 4, 4); Assert.IsTrue(CollisionHelper.PerPixelIntersect(dataA, destA, dataB, destB)); destB = new Rectangle(2, 2, 4, 4); Assert.IsFalse(CollisionHelper.PerPixelIntersect(dataA, destA, dataB, destB)); destB = new Rectangle(3, 3, 4, 4); Assert.IsFalse(CollisionHelper.PerPixelIntersect(dataA, destA, dataB, destB)); }
/// <summary> /// Determines if there is overlap in the non-transparent pixels between two Color arrays. /// </summary> /// <param name="dataA">The first Color array.</param> /// <param name="destA">The destination rectangle for Color array A.</param> /// <param name="dataB">The second Color array.</param> /// <param name="destB">The destination rectangle for Color array B.</param> public static bool PerPixelIntersect(Color[] dataA, Rectangle destA, Color[] dataB, Rectangle destB) { if (destA.Intersects(destB)) { int top = Math.Max(destA.Top, destB.Top); int bottom = Math.Min(destA.Bottom, destB.Bottom); int left = Math.Max(destA.Left, destB.Left); int right = Math.Min(destA.Right, destB.Right); for (int y = top; y < bottom; y++) { for (int x = left; x < right; x++) { Color colorA = dataA[x - destA.Left + ((y - destA.Top) * destA.Width)]; Color colorB = dataB[x - destB.Left + ((y - destB.Top) * destB.Width)]; if (colorA.A != 0 && colorB.A != 0) return true; } } } return false; }
private void DoDraw() { if (GraphicsDevice.BeginDraw()) { GraphicsDevice.Clear(new Snowball.Color(this.BackColor.R, this.BackColor.G, this.BackColor.B, this.BackColor.A)); this.OnDraw(graphicsDeviceEventArgs); GraphicsDevice.EndDraw(); Snowball.Rectangle rect = new Snowball.Rectangle(0, 0, this.Width, this.Height); GraphicsDevice.Present(rect, rect, this.Handle); } }
/// <summary> /// Returns true if r1 instersects r2. /// </summary> /// <param name="r1"></param> /// <param name="r2"></param> /// <returns></returns> public static bool Intersects(Rectangle r1, Rectangle r2) { return Intersects(ref r1, ref r2); }
/// <summary> /// Returns true if the Rectangle intersects with the other. /// </summary> /// <param name="other"></param> /// <returns></returns> public bool Intersects(ref Rectangle other) { return Intersects(ref this, ref other); }
/// <summary> /// Returns true if r1 intersects r2. /// </summary> /// <param name="r1"></param> /// <param name="r2"></param> /// <returns></returns> public static bool Intersects(ref Rectangle r1, ref Rectangle r2) { if (r2.Left > r1.Right || r2.Right < r1.Left || r2.Top > r1.Bottom || r2.Bottom < r1.Top) { return false; } return true; }
/// <summary> /// Returns true if the given Rectangle is colliding with the given axis. /// </summary> /// <param name="other"></param> /// <param name="axis"></param> /// <returns></returns> private bool IsAxisCollision(Rectangle other, Vector2 axis) { int thisMinScaler, otherMinScaler, thisMaxScaler, otherMaxScaler; // this scalers int scaler = GenerateScalar(this.topLeft, axis); thisMinScaler = scaler; thisMaxScaler = scaler; scaler = GenerateScalar(this.topRight, axis); if (scaler < thisMinScaler) thisMinScaler = scaler; if (scaler > thisMaxScaler) thisMaxScaler = scaler; scaler = GenerateScalar(this.bottomLeft, axis); if (scaler < thisMinScaler) thisMinScaler = scaler; if (scaler > thisMaxScaler) thisMaxScaler = scaler; scaler = GenerateScalar(this.bottomRight, axis); if (scaler < thisMinScaler) thisMinScaler = scaler; if (scaler > thisMaxScaler) thisMaxScaler = scaler; // other scalers scaler = GenerateScalar(new Vector2(other.Left, other.Top), axis); otherMinScaler = scaler; otherMaxScaler = scaler; scaler = GenerateScalar(new Vector2(other.Right, other.Top), axis); if (scaler < otherMinScaler) otherMinScaler = scaler; if (scaler > otherMaxScaler) otherMaxScaler = scaler; scaler = GenerateScalar(new Vector2(other.Left, other.Bottom), axis); if (scaler < otherMinScaler) otherMinScaler = scaler; if (scaler > otherMaxScaler) otherMaxScaler = scaler; scaler = GenerateScalar(new Vector2(other.Right, other.Bottom), axis); if (scaler < otherMinScaler) otherMinScaler = scaler; if (scaler > otherMaxScaler) otherMaxScaler = scaler; if (thisMinScaler <= otherMaxScaler && thisMaxScaler >= otherMaxScaler) return true; else if (otherMinScaler <= thisMaxScaler && otherMaxScaler >= thisMaxScaler) return true; return false; }
/// <summary> /// Constructor. /// </summary> /// <param name="baseRectangle"></param> public RotatableRectangle(Rectangle baseRectangle) : this(baseRectangle, Vector2.Zero, 0.0f) { }
/// <summary> /// Returns true if the Rectangle intersects the other Rectangle. /// </summary> /// <param name="other"></param> /// <returns></returns> public bool Intersects(Rectangle other) { if (this.recalculateCorners) CalculateCorners(); Vector2 axis1 = this.topRight - this.topLeft; Vector2 axis2 = this.topRight - this.bottomRight; Vector2 axis3 = new Vector2(0, other.Top - other.Bottom); Vector2 axis4 = new Vector2(other.Left - other.Right, 0); if (!IsAxisCollision(other, axis1)) return false; if (!IsAxisCollision(other, axis2)) return false; if (!IsAxisCollision(other, axis3)) return false; if (!IsAxisCollision(other, axis4)) return false; return true; }
/// <summary> /// Determines if there is overlap in the non-transparent pixels between two SpriteSheets. /// </summary> /// <param name="spriteSheetA">The first SpriteSheet.</param> /// <param name="destA">The destination rectangle for SpriteSheet A.</param> /// <param name="currentFrameA">The current frame for SpriteSheet A.</param> /// <param name="spriteSheetB">The second SpriteSheet.</param> /// <param name="destB">The destination rectangle for SpriteSheet B.</param> /// <param name="currentFrameB">The current frame for SpriteSheet B.</param> /// <returns></returns> public static bool PerPixelIntersect(SpriteSheet spriteSheetA, Rectangle destA, int currentFrameA, SpriteSheet spriteSheetB, Rectangle destB, int currentFrameB) { return PerPixelIntersect(spriteSheetA.GetColorData(), destA, spriteSheetA[currentFrameA], spriteSheetA.Texture.Width, spriteSheetB.GetColorData(), destB, spriteSheetB[currentFrameB], spriteSheetB.Texture.Width); }