Beispiel #1
0
        public async void RunTestBalls()
        {
            // Geometry
            int sideLengthY = Dimension;
            int sideLengthX = sideLengthY * 2;
            XY  TopLeft     = new XY(0, 0);
            XY  BottomRight = new XY(sideLengthX, sideLengthY);

            // Polygon prototype (for RectangleShape)
            Polygon pProto = new Polygon
            {
                Stroke          = new SolidColorBrush(Colors.DarkGray),
                StrokeThickness = 2
            };

            // Bounding rectangle and associated Drawer
            RectangleShape  rA  = new RectangleShape(TopLeft, sideLengthX, sideLengthY);
            RectangleDrawer rdA = new RectangleDrawer(rA, pProto);

            rdA.AttachToCanvas(MainCanvas.Instance.TheCanvas);

            BouncingBallCollection bbc = new BouncingBallCollection(new BouncingBallFactory(TopLeft, BottomRight, 20, 80, 1, 5), _ballCount);

            _bbcd = new BouncingBallCollectionDrawer(bbc, MainCanvas.Instance.TheCanvas);

            // Main simulation loop
            for (int i = 1; i <= LoopCount; i++)
            {
                lock (_lock)
                {
                    _bbcd.BallDrawers.ForEach(b => b.MoveAndDraw());
                }
                await Task.Delay(DelayMs);
            }
        }
Beispiel #2
0
        public override void onDraw(SpriteBatch sprite_batch)
        {
            base.onDraw(sprite_batch);
            if (this.State == AdState.Loading || this.State == AdState.Playing || this.State == AdState.NoAdsFound)
            {
                var rect = new Rectangle(0, 0, Engine.Game.CanvasWidth, Engine.Game.CanvasHeight);
                RectangleDrawer.Draw(sprite_batch, rect, new Color(0X04, 0X04, 0X04), layerDepth: 0.001f);

                var font            = ContentHolder.Get(AvailableFonts.retro_computer);
                var font_color      = new Color(0XCC, 0XCC, 0XCC);
                var splash_texture  = ContentHolder.Get(AvailableTextures.splash_ad_buffer);
                var splash_position = new Vector2(Engine.Game.CanvasWidth / 2 - splash_texture.Width / 2, 57);
                sprite_batch.Draw(splash_texture, splash_position, Color.White);
                sprite_batch.DrawString(font, "Snake Will Be Right Back", splash_position + new Vector2(splash_texture.Width / 2f, 188), font_color, scale: 0.4375f, draw_from: DrawFrom.TopCenter);

                string text;
                if (this.State == AdState.Loading)
                {
                    text = "Fetching Ad Data...";
                }
                else if (this.State == AdState.Playing)
                {
                    text = "Loading Ad";
                }
                else
                {
                    text = "No Ads Found";
                }
                sprite_batch.DrawString(font, text, new Vector2(Engine.Game.CanvasWidth / 2f, Engine.Game.CanvasHeight - 80), font_color, scale: 0.5f, draw_from: DrawFrom.TopCenter);
            }
        }
Beispiel #3
0
        private void DrawAdditionalObjects(Image <Bgr, byte> imageToDraw)
        {
            EmguCVDrawer drawer;
            TimePoint    currentPoint;

            if (tracks.Objects.Length > 0)
            {
                foreach (AdditionalObject obj in tracks.Objects)
                {
                    double[] timeValues = obj.Points.Select(p => p.Time).ToArray();
                    if (video.CurrentTimestamp >= timeValues.Min() && video.CurrentTimestamp <= timeValues.Max())
                    {
                        currentPoint = repository.LagrangeInterpolatePoint(video.CurrentTimestamp, obj.Points);
                        drawer       = new RectangleDrawer(imageToDraw, currentPoint);

                        if (isCoordinateShowModeSelected)
                        {
                            drawer = new CoordinatedRectangleDrawer(drawer);
                        }
                        if (isNameShowModeSelected)
                        {
                            drawer = new NamedRectangleDrawer(drawer, obj.Name);
                        }
                        obj.Draw(drawer);
                    }
                }
            }
        }
Beispiel #4
0
        /// <summary>
        /// Updates the position, width and height of the <paramref name="rectangle"/>,
        /// according to the proportions of the image and its container.
        /// </summary>
        /// <param name="rectangle"></param>
        /// <param name="face"></param>
        private void SetPositionAndSize(Rectangle rectangle, Face face)
        {
            var drawer = new RectangleDrawer();

            // Reposition Left
            rectangle.SetValue(Canvas.LeftProperty, drawer.LeftResize(
                                   face.FaceRectangle.Left,
                                   ImageContainer.ActualWidth,
                                   EmotionImage.ActualWidth,
                                   InitialEmotionImage.Width));
            // Reposition Top
            rectangle.SetValue(Canvas.TopProperty, drawer.TopResize(
                                   face.FaceRectangle.Top,
                                   ImageContainer.ActualHeight,
                                   EmotionImage.ActualHeight,
                                   InitialEmotionImage.Height));
            // Reposition Width
            rectangle.Width = drawer.WidthResize(
                face.FaceRectangle.Width,
                InitialEmotionImage.Width,
                EmotionImage.ActualWidth);
            // Reposition Height
            rectangle.Height = drawer.HeightResize(
                face.FaceRectangle.Height,
                InitialEmotionImage.Height,
                EmotionImage.ActualHeight);
        }
Beispiel #5
0
        public void TestRectangleDrawer()
        {
            var drawingStartingPoint = new Point();
            var drawingEndingPoint   = new Point();
            var rectangleDrawer      = new RectangleDrawer(drawingStartingPoint, drawingEndingPoint);
            var target = new PrivateObject(rectangleDrawer);

            Assert.AreSame(target.GetFieldOrProperty(MEMBER_VARIABLE_NAME_DRAWING_STARTING_POINT), drawingStartingPoint);
            Assert.AreSame(target.GetFieldOrProperty(MEMBER_VARIABLE_NAME_DRAWING_ENDING_POINT), drawingEndingPoint);
        }
Beispiel #6
0
        public void TestGetMostRecentDrawShapeDrawerThatIncludesPoint()
        {
            var rectangleDrawer = new RectangleDrawer(new Point(0.0, 0.0), new Point(5.0, 5.0));
            var lineDrawer      = new LineDrawer(new Point(0.0, 0.0), new Point(5.0, 5.0));

            _shapeDrawers.Add(rectangleDrawer);
            _shapeDrawers.Add(lineDrawer);
            Assert.AreSame(_canvasShapeDrawersHelper.GetMostRecentDrawShapeDrawerThatIsCloseToPoint(new Point(2.5, 2.5), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED), lineDrawer);
            Assert.IsNull(_canvasShapeDrawersHelper.GetMostRecentDrawShapeDrawerThatIsCloseToPoint(new Point(-0.1, 0.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
        }
        private bool isWithinSelectionBounds(Transform entity)
        {
            if (!_isSelecting)
            {
                return(false);
            }

            var mainCamera     = Camera.main;
            var viewportBounds = RectangleDrawer.GetViewportBounds(mainCamera, _mousePosition1, Input.mousePosition);

            return(viewportBounds.Contains(mainCamera.WorldToViewportPoint(entity.position)));
        }
        public void TestGetCurrentShapeType()
        {
            _target.SetFieldOrProperty(MEMBER_VARIABLE_NAME_CURRENT_SELECTED_SHAPE_SHAPE_DRAWER, null);
            Assert.AreEqual(_canvasDrawerPointerState.GetCurrentShapeType(), ShapeDrawerType.None);
            var lineDrawer = new LineDrawer(new Point(), new Point());

            _target.SetFieldOrProperty(MEMBER_VARIABLE_NAME_CURRENT_SELECTED_SHAPE_SHAPE_DRAWER, lineDrawer);
            Assert.AreEqual(_canvasDrawerPointerState.GetCurrentShapeType(), ShapeDrawerType.Line);
            var rectangleDrawer = new RectangleDrawer(new Point(), new Point());

            _target.SetFieldOrProperty(MEMBER_VARIABLE_NAME_CURRENT_SELECTED_SHAPE_SHAPE_DRAWER, rectangleDrawer);
            Assert.AreEqual(_canvasDrawerPointerState.GetCurrentShapeType(), ShapeDrawerType.Rectangle);
        }
Beispiel #9
0
        public void TestGetMostRecentDrawShapeDrawerWhoseDrawingEndingPointIsCloseToPoint()
        {
            var dumpPoint       = new Point(TestDefinitions.DUMP_DOUBLE, TestDefinitions.DUMP_DOUBLE);
            var rectangleDrawer = new RectangleDrawer(dumpPoint, new Point(5.0, 5.0));
            var firstLineDrawer = new LineDrawer(dumpPoint, new Point(5.0, 5.0));

            _shapeDrawers.Add(rectangleDrawer);
            _shapeDrawers.Add(firstLineDrawer);
            Assert.AreSame(_canvasShapeDrawersHelper.GetMostRecentDrawShapeDrawerWhoseDrawingEndingPointIsCloseToPoint(new Point(5.0, 5.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED), firstLineDrawer);
            _shapeDrawers.Add(new LineDrawer(dumpPoint, new Point(10.0, 5.0)));
            Assert.AreSame(_canvasShapeDrawersHelper.GetMostRecentDrawShapeDrawerWhoseDrawingEndingPointIsCloseToPoint(new Point(5.0, 5.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED), firstLineDrawer);
            Assert.IsNull(_canvasShapeDrawersHelper.GetMostRecentDrawShapeDrawerWhoseDrawingEndingPointIsCloseToPoint(new Point(7.0, 7.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
        }
Beispiel #10
0
        public void TestAddShapeDrawer()
        {
            Assert.ThrowsException <ArgumentNullException>(() => _canvasShapeDrawersHelper.AddShapeDrawer(null));
            var lineDrawer = new LineDrawer(new Point(), new Point());

            _canvasShapeDrawersHelper.AddShapeDrawer(lineDrawer);
            Assert.AreEqual(_shapeDrawers.Count, 1);
            Assert.AreSame(_shapeDrawers[0], lineDrawer);
            var rectangleDrawer = new RectangleDrawer(new Point(), new Point());

            _canvasShapeDrawersHelper.AddShapeDrawer(rectangleDrawer);
            Assert.AreEqual(_shapeDrawers.Count, 2);
            Assert.AreSame(_shapeDrawers[1], rectangleDrawer);
        }
Beispiel #11
0
        private void DrawTiltedRect(int tilt)
        {
            RectangleShape rA     = new RectangleShape(new XY(Dimension / 2, Dimension / 2), Dimension / 3, Dimension / 5, tilt);
            Polygon        pProto = new Polygon
            {
                Stroke          = new SolidColorBrush(Colors.Black),
                StrokeThickness = 2,
                Fill            = new SolidColorBrush(Color.FromArgb(255, (byte)((255 * tilt) / 360), 0, 0))
            };

            RectangleDrawer rdA = new RectangleDrawer(rA, pProto);

            rdA.AttachToCanvas(MainCanvas.Instance.TheCanvas);
        }
        public void TestDrawSelectionHint()
        {
            var lineDrawer = new LineDrawer(new Point(), new Point());
            var graphics   = new GraphicsMock();

            lineDrawer.DrawSelectionHint(graphics);
            Assert.IsTrue(graphics.IsCalledDrawSelectionCorner);
            Assert.IsTrue(graphics.IsCalledDrawSelectionBorderLine);
            var rectangleDrawer = new RectangleDrawer(new Point(), new Point());

            graphics = new GraphicsMock();
            rectangleDrawer.DrawSelectionHint(graphics);
            Assert.IsTrue(graphics.IsCalledDrawSelectionCorner);
            Assert.IsTrue(graphics.IsCalledDrawSelectionBorderRectangle);
        }
Beispiel #13
0
 public ButtonLevels() : base(Engine.Game.CanvasWidth / 2, Engine.Game.CanvasHeight / 2 + 20, 215, 120)
 {
     this.ExtraDrawingBegin = sprite_batch => {
         const float extra_rect_alpha = (48 / 255f);
         const float rect_width       = 60;
         const float rect_height      = 34;
         var         scaled_pos       = new Vector2(
             this.Position.X - (this.BaseWidth / 2f) * this.Scale,
             this.Position.Y - (this.BaseHeight / 2f) * this.Scale);
         foreach (var lock_location in ButtonLevels.LockLocations)
         {
             RectangleDrawer.Draw(sprite_batch, scaled_pos.X + lock_location.X * this.Scale, scaled_pos.Y + lock_location.Y * this.Scale, rect_width * this.Scale, rect_height * this.Scale, Color.Black * extra_rect_alpha);
         }
         RectangleDrawer.Draw(sprite_batch, scaled_pos.X + 9 * this.Scale, scaled_pos.Y + 44 * this.Scale, rect_width * this.Scale, rect_height * this.Scale, Color.Black * extra_rect_alpha);
     };
 }
        public void TestIsCloseToPoint()
        {
            var rectangleDrawer = new RectangleDrawer(new Point(1.0, 5.0), new Point(-1.0, 2.0));

            Assert.IsTrue(rectangleDrawer.IsCloseToPoint(new Point(0.5, 3.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsFalse(rectangleDrawer.IsCloseToPoint(new Point(-1.1, 2.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsFalse(rectangleDrawer.IsCloseToPoint(new Point(1.1, 2.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsFalse(rectangleDrawer.IsCloseToPoint(new Point(-1.0, 1.9), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsFalse(rectangleDrawer.IsCloseToPoint(new Point(-1.0, 5.1), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            var lineDrawer = new LineDrawer(new Point(1.0, 5.0), new Point(-1.0, 2.0));

            Assert.IsTrue(lineDrawer.IsCloseToPoint(new Point(0.0, 3.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsTrue(lineDrawer.IsCloseToPoint(new Point(0.5, 3.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsFalse(lineDrawer.IsCloseToPoint(new Point(-2.0, 2.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsTrue(lineDrawer.IsCloseToPoint(new Point(0.0, 2.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsFalse(lineDrawer.IsCloseToPoint(new Point(1.0, 6.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
            Assert.IsTrue(lineDrawer.IsCloseToPoint(new Point(1.0, 4.0), Definitions.MOUSE_POSITION_TO_SELECTION_SHAPE_MAXIMUM_DISTANCE_SQUARED));
        }
Beispiel #15
0
        public override void onDraw(SpriteBatch sprite_batch)
        {
            base.onDraw(sprite_batch);
            if (!(Engine.Room is RoomMain))
            {
                return;
            }

            if (!Upgrade.IsUpgraded && !this.FetchingIsUpgraded)
            {
                if (Settings.CurrentTheme == 6 || Settings.CurrentTheme == 7)
                {
                    Color wall_color;
                    if (Settings.CurrentTheme == 6)
                    {
                        wall_color = new Color(0xdf, 0x5a, 0x1f);
                    }
                    else
                    {
                        wall_color = new Color(0x84, 0xb0, 0x4e);
                    }
                    RectangleDrawer.Draw(sprite_batch, this.Position.X - Wall.Size / 2f, this.Position.Y - Wall.Size / 2f, Wall.Size, Wall.Size, wall_color);
                }

                var background_color = Color.White;
                if (Settings.CurrentTheme < this.BackgroundColors.Length)
                {
                    background_color = this.BackgroundColors[Settings.CurrentTheme];
                }
                RectangleDrawer.Draw(sprite_batch, this.Position.X - Wall.Size / 2f + 4, this.Position.Y - Wall.Size / 2f + 4, Wall.Size - 8, Wall.Size - 8, background_color);

                var text_color = Color.Black;
                if (Settings.CurrentTheme < this.FoodColors.Length)
                {
                    text_color = this.FoodColors[Settings.CurrentTheme];
                }
                for (int i = 0; i < 3; i++)
                {
                    RectangleDrawer.Draw(sprite_batch, this.Position.X - 8, this.Position.Y - 1.5f - 5 + 5 * i, 16, 3, text_color);
                }
                sprite_batch.DrawString(ContentHolder.Get(AvailableFonts.retro_computer), "Upgrade", this.Position + new Vector2(Wall.Size / 2 + 3, 0), text_color, scale: 0.3125f, draw_from: DrawFrom.LeftCenter);
            }
        }
        void OnGUI()
        {
            if (!_isSelecting)
            {
                return;
            }

            // Create a rect from both mouse positions
            var rect = RectangleDrawer.GetScreenRect(_mousePosition1, Input.mousePosition);

            RectangleDrawer.DrawScreenRect(rect, new Color(0.8f, 0.8f, 0.95f, 0.25f));
            RectangleDrawer.DrawScreenRectBorder(rect, 2, new Color(0.8f, 0.8f, 0.95f));

            for (int i = 0; i < transform.childCount; i++)
            {
                Transform entity = transform.GetChild(i);

                entity.GetComponent <PersonController>().SetSelected(isWithinSelectionBounds(entity));
            }
        }
Beispiel #17
0
        /// <summary>
        /// 使用指定图形绘制对象从指定位置开始绘制页面框架
        /// </summary>
        /// <param name="g">图形绘制对象</param>
        /// <param name="ClipRectangle">剪切矩形</param>
        public void DrawPageFrame(
            System.Drawing.Graphics g,
            System.Drawing.Rectangle ClipRectangle)
        {
            //Debug.WriteLine("DrawPageFrame");
            using (RectangleDrawer drawer = new RectangleDrawer())
            {
                drawer.Bounds = this.myBounds;
                if (this.intBorderColor.A != 0 && this.intBorderWidth > 0)
                {
                    drawer.BorderPen = new System.Drawing.Pen(this.intBorderColor, (float)this.intBorderWidth);
                }
                if (this.intBackColor.A != 0)
                {
                    drawer.FillBrush = new System.Drawing.SolidBrush(this.intBackColor);
                }
                if (drawer.Draw(g, ClipRectangle))
                {
                    if (this.bolDrawMargin &&
                        this.intMarginLineColor.A != 0 &&
                        this.intMarginLineLength > 0)
                    {
                        System.Drawing.Rectangle rect = new System.Drawing.Rectangle(
                            myBounds.Left + this.intLeftMargin,
                            myBounds.Top + this.intTopMargin + this.PageHeaderHeight,
                            myBounds.Width - this.intLeftMargin - this.intRightMargin,
                            myBounds.Height - this.intTopMargin - this.intBottomMargin - this.PageHeaderHeight - this.PageFooterHeight);

                        System.Drawing.Point[] ps = new System.Drawing.Point[16];
                        ps[0]   = rect.Location;
                        ps[1].X = rect.Left - intMarginLineLength;
                        ps[1].Y = rect.Top;

                        ps[2]   = ps[0];
                        ps[3].X = rect.Left;
                        ps[3].Y = rect.Top - intMarginLineLength;

                        ps[4].X = rect.Right;
                        ps[4].Y = rect.Top;
                        ps[5].X = rect.Right + intMarginLineLength;
                        ps[5].Y = rect.Top;

                        ps[6]   = ps[4];
                        ps[7].X = rect.Right;
                        ps[7].Y = rect.Top - intMarginLineLength;

                        ps[8].X = rect.Right;
                        ps[8].Y = rect.Bottom;
                        ps[9].X = rect.Right + intMarginLineLength;
                        ps[9].Y = rect.Bottom;

                        ps[10]   = ps[8];
                        ps[11].X = rect.Right;
                        ps[11].Y = rect.Bottom + intMarginLineLength;

                        ps[12].X = rect.Left;
                        ps[12].Y = rect.Bottom;
                        ps[13].X = rect.Left;
                        ps[13].Y = rect.Bottom + intMarginLineLength;

                        ps[14]   = ps[12];
                        ps[15].X = rect.Left - intMarginLineLength;
                        ps[15].Y = rect.Bottom;

                        Common.MathCommon.RectangleClipLines(myBounds, ps);
                        using (System.Drawing.Pen p = new System.Drawing.Pen(this.intMarginLineColor, 1))
                        {
                            //是否画上边距线,如果不画,则应用背景色画它,否则会有上次遗留
                            if (this.DrawTopMargin)
                            {
                                p.Color = this.intMarginLineColor;
                            }
                            else
                            {
                                p.Color = this.BackColor;
                            }

                            for (int iCount = 0; iCount < 8; iCount += 2)
                            {
                                g.DrawLine(p, ps[iCount], ps[iCount + 1]);
                            }

                            //是否画下边距线,如果不画,则应用背景色画它,否则会有上次遗留
                            if (this.DrawBottomMargin)
                            {
                                p.Color = this.intMarginLineColor;
                            }
                            else
                            {
                                p.Color = this.BackColor;
                            }

                            for (int iCount = 8; iCount < 16; iCount += 2)
                            {
                                g.DrawLine(p, ps[iCount], ps[iCount + 1]);
                            }

                            //画装订线
                            //p.Color = Color.Red;
                            //g.DrawLine(p, myBounds.Left + this.LeftMargin, myBounds.Height / 2 - 20, myBounds.Left + this.LeftMargin, myBounds.Height / 2 + 20);
                        } //using( System.Drawing.Pen p = new System.Drawing.Pen( this.intMarginLineColor , 1 ))
                    }     //if( this.bolDrawMargin && this.intMarginLineColor.A != 0 )
                }         //if( drawer.Draw( g , ClipRectangle ))
            }             //using( RectangleDrawer drawer = new RectangleDrawer() )
        }                 //public void DrawPageFrame()
 public void Initialize()
 {
     _rectangleDrawer = new RectangleDrawer(new Point(), new Point());
     _target          = new PrivateObject(_rectangleDrawer);
 }
Beispiel #19
0
        public override void onDraw(SpriteBatch sprite_batch)
        {
            base.onDraw(sprite_batch);

            var scaled_pos = new Vector2(
                this.Position.X - (this.BaseWidth / 2f) * this.Scale,
                this.Position.Y - (this.BaseHeight / 2f) * this.Scale);
            float scaled_width  = this.BaseWidth * this.Scale;
            float scaled_height = this.BaseHeight * this.Scale;
            var   vector_zero   = Vector2.Zero;
            var   textures      = new Dictionary <DrawDataTextures, Texture2D> {
                [DrawDataTextures.Snake]  = this.SnakeTexture,
                [DrawDataTextures.Food]   = this.FoodTexture,
                [DrawDataTextures.Wall]   = this.WallTexture,
                [DrawDataTextures.Portal] = ContentHolder.Get(AvailableTextures.portal_0)
            };

            // Cut out the base position from background and redraw (applicable for user imported themes)
            var background = new Region(this.BackgroundTexture, this.BaseX - this.BaseWidth / 2, this.BaseY - this.BaseHeight / 2, this.BaseWidth, this.BaseHeight, 0, 0);

            sprite_batch.Draw(background, scaled_pos, Color.White, 0, new Vector2(this.Scale));

            // Draw transparent overlay and borders
            float       edge  = 2 * this.Scale;
            const float alpha = (28 / 255f);

            RectangleDrawer.Draw(sprite_batch, scaled_pos.X, scaled_pos.Y, scaled_width, scaled_height, Color.Black * alpha);
            if (this.ShouldDrawBorder)
            {
                RectangleDrawer.Draw(sprite_batch, scaled_pos.X, scaled_pos.Y, scaled_width, edge, Color.Black * alpha);
                RectangleDrawer.Draw(sprite_batch, scaled_pos.X, scaled_pos.Y + scaled_height - edge, scaled_width, edge, Color.Black * alpha);
                RectangleDrawer.Draw(sprite_batch, scaled_pos.X, scaled_pos.Y + edge, edge, scaled_height - edge * 2, Color.Black * alpha);
                RectangleDrawer.Draw(sprite_batch, scaled_pos.X + scaled_width - edge, scaled_pos.Y + edge, edge, scaled_height - edge * 2, Color.Black * alpha);
            }

            this.ExtraDrawingBegin?.Invoke(sprite_batch);

            for (int i = 0; i < this.DrawData.Length; i++)
            {
                var data    = this.DrawData[i];
                var texture = textures[data.DrawDataTexture];
                for (int j = 0; j < data.Locations.Length; j++)
                {
                    var pos = data.Locations[j];
                    var source_rectangle = new Rectangle(0, 0, texture.Width, texture.Height);;

                    // Cut off left and top if necessary
                    if (pos.X < 0)
                    {
                        source_rectangle.X      = (int)(-pos.X / data.Scale);
                        source_rectangle.Width -= source_rectangle.X;
                        pos.X += source_rectangle.X * data.Scale;
                    }
                    if (pos.Y < 0)
                    {
                        source_rectangle.Y       = (int)(-pos.Y / data.Scale);
                        source_rectangle.Height -= source_rectangle.Y;
                        pos.Y += source_rectangle.Y * data.Scale;
                    }

                    // Cut off right and bottom if necessary
                    float right_x = pos.X + source_rectangle.Width * data.Scale;
                    if (right_x > this.BaseWidth)
                    {
                        source_rectangle.Width -= (int)((right_x - this.BaseWidth) / data.Scale);
                    }
                    float bottom_y = pos.Y + source_rectangle.Height * data.Scale;
                    if (bottom_y > this.BaseHeight)
                    {
                        source_rectangle.Height -= (int)((bottom_y - this.BaseHeight) / data.Scale);
                    }

                    sprite_batch.Draw(texture, scaled_pos + pos * this.Scale, source_rectangle, Color.White, 0, vector_zero, data.Scale * this.Scale, SpriteEffects.None, 0);
                }
            }

            this.ExtraDrawingEnd?.Invoke(sprite_batch);
        }