diff --git a/4/4.cs b/4/4.cs index d70731d..b2de08c 100644 --- a/4/4.cs +++ b/4/4.cs @@ -173,46 +173,17 @@ namespace LaptopSimulator2015.Levels get { for (int i = 0; i < platforms.Count; i++) { - RectangleF rect = plat2rect(i); - if (player.X < rect.X) - { - if (player.Y < rect.Y) - platforms[i].Tag = (player - new PointF(rect.X, rect.Y)).magnitude; - else if (player.Y > rect.Y + rect.Height) - platforms[i].Tag = (player - new PointF(rect.X, rect.Y + rect.Height)).magnitude; - else - platforms[i].Tag = rect.X - player.X; - } - else if (player.X > rect.X + rect.Width) - { - if (player.Y < rect.Y) - platforms[i].Tag = (player - new PointF(rect.X + rect.Width, rect.Y)).magnitude; - else if (player.Y > rect.Y + rect.Height) - platforms[i].Tag = (player - new PointF(rect.X + rect.Width, rect.Y + rect.Height)).magnitude; - else - platforms[i].Tag = player.X - rect.X + rect.Width; - } - else - { - if (player.Y < rect.Y) - platforms[i].Tag = rect.Y - player.Y; - else if (player.Y > rect.Y + rect.Height) - platforms[i].Tag = player.Y - (rect.Y + rect.Height); - else - platforms[i].Tag = 0d; - } - if (((double)platforms[i].Tag) <= 20 && RectangleF.Intersect(player2rect(), rect) != RectangleF.Empty && player.Y > platforms[i].Y + 8) + Rect rect = new Rect(platforms[i], new Vector2(100, 10), true); + if (player.distanceToRectSquared(rect) <= 20 && rect.doOverlap(new Rect(player, new Vector2(10, 10), true)) && platforms[i].Y + 11 > player.Y && player.Y > platforms[i].Y + 9) return true; } return false; } } - RectangleF plat2rect(int platform) => new RectangleF((platforms[platform] - new Vector2(50, 5)).toPointF(), new SizeF(100, 10)); - RectangleF player2rect() => new RectangleF((player - new Vector2(5, 5)).toPointF(), new SizeF(10, 10)); public void draw(GraphicsWrapper g, Panel minigamePanel, Timer minigameTimer, uint minigameTime) { - g.DrawRectangle(new RectangleF(player.toPointF(), new SizeF(10, 10)), Color.Green); + g.DrawRectangle(new Rect(player, new Vector2(10, 10), true), Color.Green); if (lazorTime >= 0 && lazorTime <= 80) { g.DrawRectangle(new RectangleF((float)lazor, minigamePanel.Height / 2, 2, minigamePanel.Height), Color.DarkGray); @@ -220,7 +191,7 @@ namespace LaptopSimulator2015.Levels g.DrawRectangle(new RectangleF((float)lazor, minigamePanel.Height - m / 2, 2, m), Color.Red); } for (int i = 0; i < platforms.Count; i++) - g.DrawRectangle(new RectangleF(platforms[i].toPointF(), new SizeF(100, 10)), Color.White); + g.DrawRectangle(new Rect(platforms[i], new Vector2(100, 10), true), Color.White); } } } diff --git a/Base/Base.csproj b/Base/Base.csproj index 54e9950..d7c643c 100644 --- a/Base/Base.csproj +++ b/Base/Base.csproj @@ -49,6 +49,7 @@ + diff --git a/Base/Drawing.cs b/Base/Drawing.cs index bd27cb5..e6c3ffa 100644 --- a/Base/Drawing.cs +++ b/Base/Drawing.cs @@ -79,6 +79,15 @@ namespace Base g.DrawRectangle(new Pen(b, unfilledLineSize), new Rectangle(Misc.f2i(r.X), Misc.f2i(r.Y), Misc.f2i(r.Width), Misc.f2i(r.Height))); } + /// + /// Draws a rectangle + /// + /// The rectangle to be drawn + /// The color of the rectangle + /// Whether the rectangle should be filled + /// The size of the lines used when not filling + public void DrawRectangle(Rect rectangle, Color color, bool filled = true, int unfilledLineSize = 1) => DrawRectangle(rectangle.toRectangleF(), color, false, true, filled, unfilledLineSize); + public void Clear() => g.Clear(backColor); public void Dispose() diff --git a/Base/Rect.cs b/Base/Rect.cs new file mode 100644 index 0000000..dc08c41 --- /dev/null +++ b/Base/Rect.cs @@ -0,0 +1,116 @@ +using System; +using System.Drawing; + +namespace Base +{ + public class Rect + { + public Vector2 Location; + public Vector2 Size; + bool centered; + + /// + /// Create a rect from the provided data + /// + /// Bottom-left point + /// Amount to extend top-right + public Rect(Vector2 Location, Vector2 Size, bool centered = false) + { + this.Location = Location ?? throw new ArgumentNullException(nameof(Location)); + this.Size = Size ?? throw new ArgumentNullException(nameof(Size)); + this.centered = centered; + if (this.centered) + this.Location -= this.Size / 2; + } + + /// + /// Create a rect from the provided data + /// + /// X in world-coordinates + /// Y in world-coordinates + /// Width + /// Height + public Rect(double X, double Y, double Width, double Height, bool centered = false) + { + Location = new Vector2(X, Y); + Size = new Vector2(Width, Height); + this.centered = centered; + if (this.centered) + Location -= Size / 2; + } + + /// + /// Copies the Rect's data + /// + /// + public Rect(Rect rect) + { + Location = rect.Location; + Size = rect.Size; + } + public Rect(Rectangle rect) + { + Location = new Vector2(rect.Location); + Size = new Vector2(rect.Size); + } + public Rect(RectangleF rect) + { + Location = new Vector2(rect.Location); + Size = new Vector2(rect.Size); + } + + public double X + { + get => Location.X; + set => Location.X = value; + } + + public double Y + { + get => Location.Y; + set => Location.Y = value; + } + + public double Width + { + get => Size.X; + set { + if (centered) + { + double tmp = Size.X - value; + Size.X = value; + Location.X += tmp / 2; + } + else + Size.X = value; + } + } + + public double Height + { + get => Size.Y; + set { + if (centered) + { + double tmp = Size.Y - value; + Size.Y = value; + Location.Y += tmp / 2; + } + else + Size.Y = value; + } + } + + public double Bottom => Location.Y; + public double Top => Location.Y + Size.Y; + public double Left => Location.X; + public double Right => Location.X + Size.X; + public Vector2 bottomLeftPoint => new Vector2(Location); + public Vector2 bottomRightPoint => new Vector2(Location.X, Location.Y + Size.Y); + public Vector2 topLeftPoint => new Vector2(Location.X + Size.X, Location.Y); + public Vector2 topRightPoint => Location + Size; + public bool doOverlap(Rect other) => (Left <= other.Right && other.Left <= Right) || (Left >= other.Right && other.Left >= Right); + public Rectangle toRectangle() => new Rectangle(Misc.d2i(X), Misc.d2i(Y), Misc.d2i(Width), Misc.d2i(Height)); + public RectangleF toRectangleF() => new RectangleF(Misc.d2f(X), Misc.d2f(Y), Misc.d2f(Width), Misc.d2f(Height)); + } +} diff --git a/Base/Vector2.cs b/Base/Vector2.cs index 680f004..8ca47e6 100644 --- a/Base/Vector2.cs +++ b/Base/Vector2.cs @@ -128,6 +128,26 @@ namespace Base Y = from.Y; } + /// + /// Create a new Vector + /// + /// Size to copy data from + public Vector2(Size from) + { + X = from.Width; + Y = from.Height; + } + + /// + /// Create a new Vector + /// + /// Size to copy data from + public Vector2(SizeF from) + { + X = from.Width; + Y = from.Height; + } + /// /// Copy data from the Vector to a new one /// @@ -167,6 +187,37 @@ namespace Base /// The other Vector /// Distance public double distanceFrom(Vector2 other) => Math.Sqrt(distanceFromSquared(other)); + public double distanceToRectSquared(Rect rect) + { + if (X < rect.X) + { + if (Y < rect.Bottom) + return distanceFromSquared(rect.bottomLeftPoint); + else if (Y > rect.Top) + return distanceFromSquared(rect.topLeftPoint); + else + return Math.Pow(rect.Left - X, 2); + } + else if (X > rect.X + rect.Width) + { + if (Y < rect.Bottom) + return distanceFromSquared(rect.bottomRightPoint); + else if (Y > rect.Top) + return distanceFromSquared(rect.topRightPoint); + else + return Math.Pow(X - rect.Right, 2); + } + else + { + if (Y < rect.Bottom) + return Math.Pow(rect.Bottom - Y, 2); + else if (Y > rect.Top) + return Y - rect.Top; + else + return 0d; + } + } + public double distanceToRect(Rect rect) => Math.Sqrt(distanceToRectSquared(rect)); /// /// Provided for compatibility with some methods for other Vector implementations /// @@ -229,12 +280,14 @@ namespace Base public static Vector2 operator -(Vector2 left, Vector2 right) => new Vector2(left.X - right.X, left.Y - right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); public static Vector2 operator -(Vector2 left, Point right) => new Vector2(left.X - right.X, left.Y - right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); public static Vector2 operator -(Vector2 left, PointF right) => new Vector2(left.X - right.X, left.Y - right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator *(Vector2 left, double right) => new Vector2(left * new Vector2(right, right)).addData(left.Tag, left.bounds, left.bounds_wrap); public static Vector2 operator *(Vector2 left, Vector2 right) => new Vector2(left.X * right.X, left.Y * right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); - public static Vector2 operator *(Vector2 left, Point right) => new Vector2(left.X * right.X, left.Y * right.Y); - public static Vector2 operator *(Vector2 left, PointF right) => new Vector2(left.X * right.X, left.Y * right.Y); - public static Vector2 operator /(Vector2 left, Vector2 right) => new Vector2(left.X / right.X, left.Y / right.Y); - public static Vector2 operator /(Vector2 left, Point right) => new Vector2(left.X / right.X, left.Y / right.Y); - public static Vector2 operator /(Vector2 left, PointF right) => new Vector2(left.X / right.X, left.Y / right.Y); - public static Vector2 operator ^(Vector2 left, double right) => new Vector2(Math.Pow(left.X, right), Math.Pow(left.Y, right)); + public static Vector2 operator *(Vector2 left, Point right) => new Vector2(left.X * right.X, left.Y * right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator *(Vector2 left, PointF right) => new Vector2(left.X * right.X, left.Y * right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator /(Vector2 left, double right) => new Vector2(left / new Vector2(right, right)).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator /(Vector2 left, Vector2 right) => new Vector2(left.X / right.X, left.Y / right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator /(Vector2 left, Point right) => new Vector2(left.X / right.X, left.Y / right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator /(Vector2 left, PointF right) => new Vector2(left.X / right.X, left.Y / right.Y).addData(left.Tag, left.bounds, left.bounds_wrap); + public static Vector2 operator ^(Vector2 left, double right) => new Vector2(Math.Pow(left.X, right), Math.Pow(left.Y, right)).addData(left.Tag, left.bounds, left.bounds_wrap); } }