diff --git a/PrLaba1/PrLaba1/DiselLoko.cs b/PrLaba1/PrLaba1/DiselLoko.cs deleted file mode 100644 index 16e78c8..0000000 --- a/PrLaba1/PrLaba1/DiselLoko.cs +++ /dev/null @@ -1,53 +0,0 @@ -using System.Drawing; - -namespace PrLaba1; -public class DiselLoko -{ - /// - /// Скорость - /// - public int Speed { get; private set; } - /// - /// вес - /// - public double Weight { get; private set; } - /// - /// Цвет тела - /// - public Color ColorBody { get; private set; } - /// - /// цвет бака - /// - public Color ColorComportament { get; private set; } - /// - /// Признак наличия трубы - /// - public bool IsTube { get; private set; } - /// - /// Признак наличия отсека - /// - public bool IsComportament { get; private set; } - /// - /// шаг, перемещенние обьекта - /// - public double Step => Speed * 100 / Weight; - - /// - /// Инициализация - /// - /// - /// - /// - /// - /// - /// - public void Init(int speed, double weight, Color colorBody, Color Comportament, bool isTube, bool isComportament) - { - Speed = speed; - Weight = weight; - ColorBody = colorBody; - ColorComportament = Comportament; - IsTube = isTube; - IsComportament = isComportament; - } -} diff --git a/PrLaba1/PrLaba1/Direction.cs b/PrLaba1/PrLaba1/Drawnings/Direction.cs similarity index 69% rename from PrLaba1/PrLaba1/Direction.cs rename to PrLaba1/PrLaba1/Drawnings/Direction.cs index 613ab90..d2d0a6b 100644 --- a/PrLaba1/PrLaba1/Direction.cs +++ b/PrLaba1/PrLaba1/Drawnings/Direction.cs @@ -1,7 +1,11 @@ -namespace PrLaba1; +namespace PrLaba1.Drawnings; public enum Direction { + /// + /// Неизвестное направление + /// + Unknow = -1, /// ///Вверх /// diff --git a/PrLaba1/PrLaba1/Drawnings/DrawningDiselLoko.cs b/PrLaba1/PrLaba1/Drawnings/DrawningDiselLoko.cs new file mode 100644 index 0000000..a9b92a6 --- /dev/null +++ b/PrLaba1/PrLaba1/Drawnings/DrawningDiselLoko.cs @@ -0,0 +1,76 @@ +using PrLaba1.Entities; + +namespace PrLaba1.Drawnings; +/// +/// Класс, отвечающий за прорисовку и перемещение объекта-сущности +/// +public class DrawningDiselLoko : DrawningLoko +{ + + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия трубы + /// Признак наличия топливного отсека + public DrawningDiselLoko(int speed, double weight, Color bodyColor, Color Comportamen, bool isTube, bool isComportament) : base(140, 60) + { + EntityLoko = new DiselLoko(speed, weight, bodyColor, Comportamen, isTube, isComportament); + } + + + + /// + /// Прорисовка объекта + /// + /// + public override void DrawTransport(Graphics g) + { + if (EntityLoko == null || EntityLoko is not DiselLoko diselLoko || !_startPosX.HasValue || !_startPosY.HasValue) + { + return; + } + + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(diselLoko.ColorComportament); + + // труба + if (diselLoko.IsTube) + { + // **Труба (полигон)** + + Point[] chimney = { + new Point(_startPosX.Value + 20, _startPosY.Value - 20), + new Point(_startPosX.Value + 35, _startPosY.Value - 20), + new Point(_startPosX.Value + 35, _startPosY.Value), + new Point(_startPosX.Value + 20, _startPosY.Value) + }; + g.DrawPolygon(pen, chimney); + } + + _startPosX += 10;//change + _startPosY += 5; + base.DrawTransport(g); + _startPosX -= 10; + _startPosY -= 5; + + // отсек + if (diselLoko.IsComportament) + { + //Топливный отсек(полигон) + Point[] fuelTank = { + new Point(_startPosX.Value + 110, _startPosY.Value ), // Верхний левый угол + new Point(_startPosX.Value + 130, _startPosY.Value ), // Верхний правый угол + new Point(_startPosX.Value +130 , _startPosY.Value ), // Нижний правый угол + new Point(_startPosX.Value + 110, _startPosY.Value ) // Нижний левый угол + }; + g.DrawPolygon(pen, fuelTank); + } + + } + +} + diff --git a/PrLaba1/PrLaba1/DrawningDiselLoko.cs b/PrLaba1/PrLaba1/Drawnings/DrawningLoko.cs similarity index 65% rename from PrLaba1/PrLaba1/DrawningDiselLoko.cs rename to PrLaba1/PrLaba1/Drawnings/DrawningLoko.cs index ddcbe7e..6c7b1d9 100644 --- a/PrLaba1/PrLaba1/DrawningDiselLoko.cs +++ b/PrLaba1/PrLaba1/Drawnings/DrawningLoko.cs @@ -1,17 +1,16 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; +using PrLaba1.Entities; -namespace PrLaba1; +namespace PrLaba1.Drawnings; +/// +/// Класс, отвечающий за прорисовку и перемещение базового объекта-сущности +/// -public class DrawningDiselLoko +public class DrawningLoko { /// ///Класс-сущность /// - public DiselLoko? DiselLoko { get; private set; } + public EntityLoko? EntityLoko { get; protected set; } /// ///Ширина окна @@ -26,22 +25,22 @@ public class DrawningDiselLoko /// ///Левая координата прорисовки тепловоза /// - private int? _startPosX; + protected int? _startPosX; /// ///Верхняя координата прорисовки тепловоза /// - private int? _startPosY; + protected int? _startPosY; /// ///Ширина прорисовки тепловоза /// - private readonly int _drawingCarWidth = 140; + private readonly int _drawingCarWidth = 140;//поменять /// ///Высота прорисовки тепловоза /// - private readonly int _drawingCarHeight = 60; + private readonly int _drawingCarHeight = 60;//поменять /// ///Высота прорисовки тепловоза с трубой @@ -58,44 +57,78 @@ public class DrawningDiselLoko /// private int _InsertWidth = 10; - /// - ///Иницилизация - /// - /// Скорость - /// Вес - /// Цвет тела - /// Цвет колёс - /// Признак езды - /// Признак заполнености + /// + /// Координата X объекта + /// + public int? GetPosX => _startPosX; - public void Init(int speed, double weight, Color colorBody, Color colorComportament, bool isTube, bool isComportament) + /// + /// Координата Y объекта + /// + public int? GetPosY => _startPosY; + + /// + /// Ширина объекта + /// + public int GetWidth => _drawingCarWidth; + + /// + /// Высота объекта + /// + public int GetHeight => _drawingCarHeight; + + + /// + /// Пустой конструктор + /// + private DrawningLoko() { - DiselLoko = new DiselLoko(); - DiselLoko.Init(speed, weight, colorBody, colorComportament, isTube, isComportament); _pictureWidth = null; _pictureHeight = null; _startPosX = null; _startPosY = null; } + + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + public DrawningLoko(int speed, double weight, Color bodyColor) : this() + { + EntityLoko = new EntityLoko(speed, weight, bodyColor); + } + + /// + /// Конструктор для наследников + /// + /// Ширина прорисовки автомобиля + /// Высота прорисовки автомобиля + protected DrawningLoko(int drawningCarWidth, int drawningCarHeight) : this() + { + _drawingCarWidth = drawningCarWidth; + _pictureHeight = drawningCarHeight; + } + /// ///Установка границ поля /// /// Ширина поля /// Высота поля /// true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах + public bool SetPictureSize(int width, int height) { - // TODO проверка, что объект "влезает" в размеры поля - // если влезает, сохраняем границы и корректируем позицию объекта, если она была уже установлена - if (width <= _startPosX || height <= _startPosY) { return false; } - + if (width <= _startPosX || height <= _startPosY) { return false; } _pictureWidth = width; _pictureHeight = height; - + return true; } + /// /// Установка позиции /// @@ -115,7 +148,8 @@ public class DrawningDiselLoko if (y < 0) { y = 1; } - if (x + _drawingCarWidth > _pictureWidth.Value) { + if (x + _drawingCarWidth > _pictureWidth.Value) + { x = _pictureWidth.Value - _drawingCarWidth - 1; } @@ -126,7 +160,7 @@ public class DrawningDiselLoko _startPosX = x; _startPosY = y; - + } /// @@ -136,7 +170,7 @@ public class DrawningDiselLoko /// true - перемещене выполнено, false - перемещение невозможно public bool MoveTransport(Direction direction) { - if (DiselLoko == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityLoko == null || !_startPosX.HasValue || !_startPosY.HasValue) { return false; } @@ -145,34 +179,31 @@ public class DrawningDiselLoko { //влево case Direction.Left: - if (_startPosX.Value - DiselLoko.Step > 0) + if (_startPosX.Value - EntityLoko.Step > 0) { - _startPosX -= (int)DiselLoko.Step; + _startPosX -= (int)EntityLoko.Step; } return true; //вверх case Direction.Up: - - if (_startPosY.Value - _drawingCarHeightWithKit >= 0 && DiselLoko.IsTube) + + if (_startPosY.Value - _drawingCarHeightWithKit >= 0) { - _startPosY = _startPosY - (int)DiselLoko.Step; - }else if(_startPosY.Value - DiselLoko.Step > 0 && !DiselLoko.IsTube) - { - _startPosY = _startPosY - (int)DiselLoko.Step; + _startPosY = _startPosY - (int)EntityLoko.Step; } return true; // вправо case Direction.Right: - if (_startPosX.Value < _pictureWidth.Value - _drawingCarWidth-_InsertWidth) + if (_startPosX.Value < _pictureWidth.Value - _drawingCarWidth - _InsertWidth) { - _startPosX += (int)DiselLoko.Step; + _startPosX += (int)EntityLoko.Step; } return true; //вниз case Direction.Down: - if (_startPosY.Value + _WheelHeight + _drawingCarHeight < _pictureHeight.Value ) + if (_startPosY.Value + _WheelHeight + _drawingCarHeight < _pictureHeight.Value) { - _startPosY += (int)DiselLoko.Step; + _startPosY += (int)EntityLoko.Step; } return true; default: @@ -184,17 +215,17 @@ public class DrawningDiselLoko /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { - if (DiselLoko == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityLoko == null || !_startPosX.HasValue || !_startPosY.HasValue) { return; } Pen pen = new(Color.Black); - Brush additionalBrush = new SolidBrush(DiselLoko.ColorBody); + Brush additionalBrush = new SolidBrush(EntityLoko.ColorBody); Brush blueBrush = Brushes.Blue; - + Pen blackPen = new Pen(Color.Black, 2); Brush blackBrush = Brushes.Black; @@ -207,14 +238,14 @@ public class DrawningDiselLoko new Point(_startPosX.Value-10, _startPosY.Value + _drawingCarHeight/2) }; - Brush br = new SolidBrush(DiselLoko.ColorBody); + Brush br = new SolidBrush(EntityLoko.ColorBody); g.FillPolygon(br, trainBody); - + //разделительная линия - g.DrawLine(blackPen, _startPosX.Value-10, _startPosY.Value + _drawingCarHeight / 2, _startPosX.Value + 55, _startPosY.Value + _drawingCarHeight / 2); - g.DrawLine(blackPen, _startPosX.Value + 140, _startPosY.Value + _drawingCarHeight / 2, _startPosX.Value + _drawingCarHeight+15, _startPosY.Value + _drawingCarHeight / 2); + g.DrawLine(blackPen, _startPosX.Value - 10, _startPosY.Value + _drawingCarHeight / 2, _startPosX.Value + 55, _startPosY.Value + _drawingCarHeight / 2); + g.DrawLine(blackPen, _startPosX.Value + 140, _startPosY.Value + _drawingCarHeight / 2, _startPosX.Value + _drawingCarHeight + 15, _startPosY.Value + _drawingCarHeight / 2); // Окна (полигоны) Point[] window1 = { @@ -256,7 +287,7 @@ public class DrawningDiselLoko for (int i = 0; i < 4; i++) { Brush brBlack = new SolidBrush(Color.Black); - g.FillEllipse(brBlack, _startPosX.Value + (i * 35), _startPosY.Value + _drawingCarHeight, 20, 20); + g.FillEllipse(brBlack, _startPosX.Value + i * 35, _startPosY.Value + _drawingCarHeight, 20, 20); } // Черные вставки внизу корпуса (полигон) @@ -266,7 +297,7 @@ public class DrawningDiselLoko new Point(_startPosX.Value + _drawingCarWidth, _startPosY.Value + _drawingCarHeight + 10), new Point(_startPosX.Value+10, _startPosY.Value + _drawingCarHeight + 10) }; - + Point[] bottomBlack3 = { new Point(_startPosX.Value, _startPosY.Value + _drawingCarHeight), new Point(_startPosX.Value+7, _startPosY.Value + _drawingCarHeight), @@ -281,41 +312,10 @@ public class DrawningDiselLoko }; g.FillPolygon(blackBrush, bottomBlack); g.FillPolygon(blackBrush, bottomBlack3); - + // Черные вставки сбоку корпуса (полигон) g.FillRectangle(blackBrush, _startPosX.Value + _drawingCarWidth, _startPosY.Value + 10, 10, _drawingCarHeight - 20); - // труба - if (DiselLoko.IsTube) - { - // **Труба (полигон)** - _drawingCarHeightWithKit = 20; - Point[] chimney = { - new Point(_startPosX.Value + 20, _startPosY.Value - 20), - new Point(_startPosX.Value + 35, _startPosY.Value - 20), - new Point(_startPosX.Value + 35, _startPosY.Value), - new Point(_startPosX.Value + 20, _startPosY.Value) - }; - g.FillPolygon(blackBrush, chimney); - } - - // отсек - if (DiselLoko.IsComportament) - { - //Топливный отсек(полигон) - Point[] fuelTank = { - new Point(_startPosX.Value + 110, _startPosY.Value + _drawingCarHeight-20), // Верхний левый угол - new Point(_startPosX.Value + 130, _startPosY.Value + _drawingCarHeight -20), // Верхний правый угол - new Point(_startPosX.Value +130 , _startPosY.Value + _drawingCarHeight-5), // Нижний правый угол - new Point(_startPosX.Value + 110, _startPosY.Value + _drawingCarHeight-5) // Нижний левый угол - }; - Brush br2 = new SolidBrush(DiselLoko.ColorComportament); - g.FillPolygon(br2, fuelTank); - g.DrawPolygon(blackPen, fuelTank); - } - } - } - diff --git a/PrLaba1/PrLaba1/Entities/DiselLoko.cs b/PrLaba1/PrLaba1/Entities/DiselLoko.cs new file mode 100644 index 0000000..83bc9bf --- /dev/null +++ b/PrLaba1/PrLaba1/Entities/DiselLoko.cs @@ -0,0 +1,33 @@ + +namespace PrLaba1.Entities; +/// +/// Класс-сущность "Тепловоз с обвесами" +/// +public class DiselLoko : EntityLoko +{ + public Color ColorComportament { get; private set; } + /// + /// Признак наличия трубы + /// + public bool IsTube { get; private set; } + /// + /// Признак наличия отсека + /// + public bool IsComportament { get; private set; } + + /// + /// Инициализация + /// + /// Скорость + /// Вес автомобиля + /// Основной цвет + /// цвет отсека + /// признак наличия трубы + /// признак наличия отсека + public DiselLoko(int speed, double weight, Color bodyColor, Color Comportament, bool isTube, bool isComportament) : base(0, 0, Color.Black) + { + ColorComportament = Comportament; + IsTube = isTube; + IsComportament = isComportament; + } +} diff --git a/PrLaba1/PrLaba1/Entities/EntityLoko.cs b/PrLaba1/PrLaba1/Entities/EntityLoko.cs new file mode 100644 index 0000000..3ac9dfd --- /dev/null +++ b/PrLaba1/PrLaba1/Entities/EntityLoko.cs @@ -0,0 +1,39 @@ +namespace PrLaba1.Entities; +/// +/// Класс-сущность "Тепловоза" +/// +public class EntityLoko +{ + /// + /// Скорость + /// + public int Speed { get; private set; } + + /// + /// вес + /// + public double Weight { get; private set; } + + /// + /// Цвет тела + /// + public Color ColorBody { get; private set; } + /// + /// шаг, перемещенние обьекта + /// + public double Step => Speed * 100 / Weight; + + /// + /// Конструктор сущности + /// + /// + /// + /// + public EntityLoko(int speed, double weight, Color colorBody) + { + Speed = speed; + Weight = weight; + ColorBody = colorBody; + + } +} diff --git a/PrLaba1/PrLaba1/FormDiselLoko.Designer.cs b/PrLaba1/PrLaba1/FormDiselLoko.Designer.cs index 9defd17..33e0f44 100644 --- a/PrLaba1/PrLaba1/FormDiselLoko.Designer.cs +++ b/PrLaba1/PrLaba1/FormDiselLoko.Designer.cs @@ -35,6 +35,9 @@ buttonDown = new Button(); buttonRight = new Button(); ButtonLeft = new Button(); + buttonCreateLoko = new Button(); + comboBoxStrategy = new ComboBox(); + buttonStrategyStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxDiselLoko).BeginInit(); SuspendLayout(); // @@ -42,20 +45,18 @@ // pictureBoxDiselLoko.Dock = DockStyle.Fill; pictureBoxDiselLoko.Location = new Point(0, 0); - pictureBoxDiselLoko.Margin = new Padding(5, 6, 5, 6); pictureBoxDiselLoko.Name = "pictureBoxDiselLoko"; - pictureBoxDiselLoko.Size = new Size(1371, 900); + pictureBoxDiselLoko.Size = new Size(800, 450); pictureBoxDiselLoko.TabIndex = 0; pictureBoxDiselLoko.TabStop = false; // // create // - create.Location = new Point(21, 830); - create.Margin = new Padding(5, 6, 5, 6); + create.Location = new Point(12, 415); create.Name = "create"; - create.Size = new Size(129, 46); + create.Size = new Size(188, 23); create.TabIndex = 1; - create.Text = "Создать"; + create.Text = "Создать тепловоз с обвесами"; create.UseVisualStyleBackColor = true; create.Click += ButtonCreate_Click; // @@ -63,10 +64,9 @@ // buttonUp.BackgroundImage = (Image)resources.GetObject("buttonUp.BackgroundImage"); buttonUp.BackgroundImageLayout = ImageLayout.Stretch; - buttonUp.Location = new Point(1236, 736); - buttonUp.Margin = new Padding(5, 6, 5, 6); + buttonUp.Location = new Point(721, 368); buttonUp.Name = "buttonUp"; - buttonUp.Size = new Size(60, 70); + buttonUp.Size = new Size(35, 35); buttonUp.TabIndex = 2; buttonUp.UseVisualStyleBackColor = true; buttonUp.Click += ButtonMove_Click; @@ -75,10 +75,9 @@ // buttonDown.BackgroundImage = (Image)resources.GetObject("buttonDown.BackgroundImage"); buttonDown.BackgroundImageLayout = ImageLayout.Stretch; - buttonDown.Location = new Point(1236, 806); - buttonDown.Margin = new Padding(5, 6, 5, 6); + buttonDown.Location = new Point(721, 403); buttonDown.Name = "buttonDown"; - buttonDown.Size = new Size(60, 70); + buttonDown.Size = new Size(35, 35); buttonDown.TabIndex = 3; buttonDown.UseVisualStyleBackColor = true; buttonDown.Click += ButtonMove_Click; @@ -87,10 +86,9 @@ // buttonRight.BackgroundImage = (Image)resources.GetObject("buttonRight.BackgroundImage"); buttonRight.BackgroundImageLayout = ImageLayout.Stretch; - buttonRight.Location = new Point(1291, 806); - buttonRight.Margin = new Padding(5, 6, 5, 6); + buttonRight.Location = new Point(753, 403); buttonRight.Name = "buttonRight"; - buttonRight.Size = new Size(60, 70); + buttonRight.Size = new Size(35, 35); buttonRight.TabIndex = 4; buttonRight.UseVisualStyleBackColor = true; buttonRight.Click += ButtonMove_Click; @@ -99,27 +97,58 @@ // ButtonLeft.BackgroundImage = (Image)resources.GetObject("ButtonLeft.BackgroundImage"); ButtonLeft.BackgroundImageLayout = ImageLayout.Stretch; - ButtonLeft.Location = new Point(1181, 806); - ButtonLeft.Margin = new Padding(5, 6, 5, 6); + ButtonLeft.Location = new Point(689, 403); ButtonLeft.Name = "ButtonLeft"; - ButtonLeft.Size = new Size(60, 70); + ButtonLeft.Size = new Size(35, 35); ButtonLeft.TabIndex = 5; ButtonLeft.TextImageRelation = TextImageRelation.TextBeforeImage; ButtonLeft.UseVisualStyleBackColor = true; ButtonLeft.Click += ButtonMove_Click; // + // buttonCreateLoko + // + buttonCreateLoko.Location = new Point(218, 415); + buttonCreateLoko.Name = "buttonCreateLoko"; + buttonCreateLoko.Size = new Size(188, 23); + buttonCreateLoko.TabIndex = 6; + buttonCreateLoko.Text = "Создать тепловоз"; + buttonCreateLoko.UseVisualStyleBackColor = true; + buttonCreateLoko.Click += buttonCreateLoko_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" }); + comboBoxStrategy.Location = new Point(667, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 7; + // + // buttonStrategyStep + // + buttonStrategyStep.Location = new Point(713, 41); + buttonStrategyStep.Name = "buttonStrategyStep"; + buttonStrategyStep.Size = new Size(75, 23); + buttonStrategyStep.TabIndex = 8; + buttonStrategyStep.Text = "Шаг"; + buttonStrategyStep.UseVisualStyleBackColor = true; + buttonStrategyStep.Click += buttonStrategyStep_Click; + // // FormDiselLoko // - AutoScaleDimensions = new SizeF(12F, 30F); + AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(1371, 900); + ClientSize = new Size(800, 450); + Controls.Add(buttonStrategyStep); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonCreateLoko); Controls.Add(ButtonLeft); Controls.Add(buttonRight); Controls.Add(buttonDown); Controls.Add(buttonUp); Controls.Add(create); Controls.Add(pictureBoxDiselLoko); - Margin = new Padding(5, 6, 5, 6); Name = "FormDiselLoko"; Text = "Тепловоз"; ((System.ComponentModel.ISupportInitialize)pictureBoxDiselLoko).EndInit(); @@ -134,5 +163,8 @@ private Button buttonDown; private Button buttonRight; private Button ButtonLeft; + private Button buttonCreateLoko; + private ComboBox comboBoxStrategy; + private Button buttonStrategyStep; } } \ No newline at end of file diff --git a/PrLaba1/PrLaba1/FormDiselLoko.cs b/PrLaba1/PrLaba1/FormDiselLoko.cs index d99f9cf..d8ad6d2 100644 --- a/PrLaba1/PrLaba1/FormDiselLoko.cs +++ b/PrLaba1/PrLaba1/FormDiselLoko.cs @@ -1,4 +1,7 @@ -namespace PrLaba1 +using PrLaba1.Drawnings; +using PrLaba1.MovementStrategy; + +namespace PrLaba1 /// /// Форма работы с объектом "Тепловоз" /// @@ -8,23 +11,12 @@ /// /// Поле-объект для прорисовки объекта /// - private DrawningDiselLoko? _drawningDiselLoko; + private DrawningLoko? _drawningLoko; - /// - /// Метод прорисовки машины + // + /// Стратегия перемещения /// - private void Draw() - { - if (_drawningDiselLoko == null) - { - return; - } - - Bitmap bmp = new(pictureBoxDiselLoko.Width, pictureBoxDiselLoko.Height); - Graphics gr = Graphics.FromImage(bmp); - _drawningDiselLoko.DrawTransport(gr); - pictureBoxDiselLoko.Image = bmp; - } + private AbstractStrategy? _strategy; /// /// Конструктор формы @@ -32,30 +24,73 @@ public FormDiselLoko() { InitializeComponent(); + _strategy = null; } /// - /// Кнопка создать + /// Метод прорисовки машины /// - private void ButtonCreate_Click(object sender, EventArgs e) + private void Draw() { - Random random = new Random(); - _drawningDiselLoko = new DrawningDiselLoko(); - _drawningDiselLoko.Init(random.Next(100, 300), random.Next(1000, 3000), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), - Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); - _drawningDiselLoko.SetPictureSize(pictureBoxDiselLoko.Width, pictureBoxDiselLoko.Height); - _drawningDiselLoko.SetPosition(random.Next(10, 100), random.Next(10, 100)); + if (_drawningLoko == null) + { + return; + } + Bitmap bmp = new(pictureBoxDiselLoko.Width, pictureBoxDiselLoko.Height); + Graphics gr = Graphics.FromImage(bmp); + _drawningLoko.DrawTransport(gr); + pictureBoxDiselLoko.Image = bmp; + } + + /// + /// Создание объекта класса-перемещения + /// + /// Тип создаваемого объекта + private void CreateObject(string type) + { + Random random = new(); + switch (type) + { + case nameof(DrawningLoko): + _drawningLoko = new DrawningLoko(random.Next(100, 300), random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256))); + break; + case nameof(DrawningDiselLoko): + _drawningLoko = new DrawningDiselLoko(random.Next(100, 300), random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); + break; + default: + return; + } + + _drawningLoko.SetPictureSize(pictureBoxDiselLoko.Width, pictureBoxDiselLoko.Height); + _drawningLoko.SetPosition(random.Next(10, 100), random.Next(10, 100)); + _strategy = null; + comboBoxStrategy.Enabled = true; Draw(); } + + /// + /// Обработка нажатия кнопки "Создать тепловоз с обвесами" + /// + private void ButtonCreate_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningDiselLoko)); + + /// + /// Обработка нажатия кнопки "Создать тепловоз" + /// + /// + /// + private void buttonCreateLoko_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningLoko)); + /// /// Кнопки движения /// private void ButtonMove_Click(object sender, EventArgs e) { - if (_drawningDiselLoko == null) + if (_drawningLoko == null) { return; } @@ -65,16 +100,16 @@ switch (name) { case "buttonUp": - result = _drawningDiselLoko.MoveTransport(Direction.Up); + result = _drawningLoko.MoveTransport(Direction.Up); break; case "buttonDown": - result = _drawningDiselLoko.MoveTransport(Direction.Down); + result = _drawningLoko.MoveTransport(Direction.Down); break; case "ButtonLeft": - result = _drawningDiselLoko.MoveTransport(Direction.Left); + result = _drawningLoko.MoveTransport(Direction.Left); break; case "buttonRight": - result = _drawningDiselLoko.MoveTransport(Direction.Right); + result = _drawningLoko.MoveTransport(Direction.Right); break; } @@ -83,5 +118,48 @@ Draw(); } } + + /// + /// Обработка нажатия кнопки "Шаг" + /// + /// + /// + private void buttonStrategyStep_Click(object sender, EventArgs e) + { + if (_drawningLoko == null) + { + return; + } + + if (comboBoxStrategy.Enabled) + { + _strategy = comboBoxStrategy.SelectedIndex switch + { + 0 => new MoveToCentre(), + 1 => new MoveToBoarder(), + _ => null, + }; + if (_strategy == null) + { + return; + } + _strategy.SetData(new MoveableLoko(_drawningLoko), pictureBoxDiselLoko.Width, pictureBoxDiselLoko.Height); + } + + if (_strategy == null) + { + return; + } + + comboBoxStrategy.Enabled = false; + _strategy.MakeStep(); + Draw(); + + if (_strategy.GetStatus() == StrategyStatus.Finish) + { + comboBoxStrategy.Enabled = true; + _strategy = null; + } + } } } diff --git a/PrLaba1/PrLaba1/FormDiselLoko.resx b/PrLaba1/PrLaba1/FormDiselLoko.resx index 75de1b3..3f46bf3 100644 --- a/PrLaba1/PrLaba1/FormDiselLoko.resx +++ b/PrLaba1/PrLaba1/FormDiselLoko.resx @@ -121,35 +121,34 @@ iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vwAADr8BOAVTJAAAAKxJREFUSEvdzEsOwjAUQ9Hsf9MgBRU5N+/jQjvpmSV+9njdZvDjOo+fHhN/c+7p - Z/fUunWnu/56f8TViUeR/oirB95tmgvurXi96uISr1dVzKUIOyLNuJFgTaQZN3JsHuKA7Q77U/J7EvtT - 8Muehyv7NBs27Fw5va9v7z9wCu+f17kSTn+xHWFHlJmBHVFmBnZEmRnYEWVmYEeUmYEdUWYGdkSZGdgR - ZWZgR7wBm1XCkmZMrk8AAAAASUVORK5CYII= + vQAADr0BR/uQrQAAAIdJREFUSEvtzFsOgCAMRFH3v2kkcjUFC6U+MCacP+jMLOE1c7rgmF42PDr0RtNu + wpelK8ekwKHJDjGW49Z0cTriXGckmKkgVPHRNANNRDXVG1ULac3d6YjCiX6g1I1abuw0cSfKQvlF0I++ + 8Nh0xMRu4HRE0ImyoHwdKDUR1czpwpwu/HE6hBWbVcKS8nHq8gAAAABJRU5ErkJggg== iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vwAADr8BOAVTJAAAAKZJREFUSEvtzEEOwzAMA8H8/9MtECAFs5ZoKrl2bjZFHp/eEWBH2CzAjrBZgB1h - swA7wmYBdoTNAuwImwXYETYLsCNsFmBHFBnbGa6s02xMcIrvFziF95t17uD9eJor5fSDdfZPze8Q+6f6 - d7TO5qUN8nXWLm0QTrMjXLZd5/XdLrZ4fbeJzTrvFvuLbp1Hi/1FOc2LSnSEdWaN9O63zt/e4HTqPw1f - 0c/CkmqWjm8AAAAASUVORK5CYII= + vQAADr0BR/uQrQAAAIVJREFUSEvtzFsKgDAMRFH3v+k6yBXsI22iUkF6PpOZ2ZJtcyDasqYLa7rwm2lK + QZQvyhPBW5g4TZwWgnH0T69NU75onIS4G7Xc9Gmh5EChYj6E6gjpytNpoi29nzBgIGT4blqYqfC2jRPC + WI6f7eY0jy5XSJg8cBrx5iS0K4Fo1JrOpLQD0c/CkunHhukAAAAASUVORK5CYII= iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vwAADr8BOAVTJAAAAIRJREFUSEvtzEEKwCAMBVHvf+kWFEuY1BjTuCj4lvoz5dqm8CHPScMkXTp+OFg3 - TzdWtw6Qbjgas6asCpy+4Y0fSwoPVrEncBrDasVRGMOJaV3n90c/TMtuZhrdnDSTHXer2BM49WNJsRaM - ddwNWDsmK47GrGk42kwOYtEmeOZx0rAxfQP0JcKSXR+eRgAAAABJRU5ErkJggg== + vQAADr0BR/uQrQAAAIZJREFUSEvtzUkOgCAMQFHuf2lM4JMgMnSAuOHtbMs3xGNuuvFfOhR8a8zeUC2Y + iinSGTsBdTrjYopTAwJj3JmR6eHCidgbOz96FRZbkCyY7kI1YbQL1YTRFiQLpn70Kiw8KH2wNiPTw4UB + gTHLb1mvqNPsBBRppmKLB7ZoZnwmcdONY+kYH/QlwpJxqZGzAAAAAElFTkSuQmCC iVBORw0KGgoAAAANSUhEUgAAAB4AAAAeCAIAAAC0Ujn1AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAO - vwAADr8BOAVTJAAAAIVJREFUSEvtzEkOwCAMBEH+/+lEwiIaGmT2nKgjYzo8xwQ+7HPTMJkOEV9zjblk - 0Q9n4W2AqOGR8DbFZMI74W2GsX4sCZ6OYi/h3QQmt0TNqS7S3Bb9lN5cR3pnneGIR3NYFTwdxV6BH/qx - VMM/gqfC24DViEfC26oOprXOIdeYV9w0HEy/eP/CkookNBkAAAAASUVORK5CYII= + vQAADr0BR/uQrQAAAJNJREFUSEvt0EEOgCAMBVHuf2k0MBiRr0CLiQvfjraZBSG+5k9ffC8dEh43ptM5 + emCqTKSJ1dgpo2lKDdZKP03DgIDChRmZBmsPSics/OgVTJcgmTBahWrCaBWqBdMlSJ6w8KNXY+dETOHC + jMw97gwIPOJU4UIZSmfEauyUiXRGsmCqTKd3VHufaUkP+tMXr6Vj3AB4/8KSzy1jIwAAAABJRU5ErkJg + gg== \ No newline at end of file diff --git a/PrLaba1/PrLaba1/MovementStrategy/AbstractStrategy.cs b/PrLaba1/PrLaba1/MovementStrategy/AbstractStrategy.cs new file mode 100644 index 0000000..fa48a01 --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/AbstractStrategy.cs @@ -0,0 +1,139 @@ + +namespace PrLaba1.MovementStrategy; +/// +/// Класс-стратегия перемещения объекта +/// +public abstract class AbstractStrategy +{ + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + + /// + /// Статус перемещения + /// + private StrategyStatus _state = StrategyStatus.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + + /// + /// Статус перемещения + /// + public StrategyStatus GetStatus() { return _state; } + + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + public void SetData(IMoveableObject moveableObject, int width, int height) + { + if (moveableObject == null) + { + _state = StrategyStatus.NotInit; + return; + } + + _state = StrategyStatus.InProgress; + _moveableObject = moveableObject; + FieldWidth = width; + FieldHeight = height; + } + + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != StrategyStatus.InProgress) + { + return; + } + + if (IsTargetDestinaion()) + { + _state = StrategyStatus.Finish; + return; + } + + MoveToTarget(); + } + + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveLeft() => MoveTo(MovementDirection.Left); + + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveRight() => MoveTo(MovementDirection.Right); + + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveUp() => MoveTo(MovementDirection.Up); + + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveDown() => MoveTo(MovementDirection.Down); + + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition; + + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != StrategyStatus.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - неудача) + private bool MoveTo(MovementDirection movementDirection) + { + if (_state != StrategyStatus.InProgress) + { + return false; + } + + return _moveableObject?.TryMoveObject(movementDirection) ?? false; + } +} diff --git a/PrLaba1/PrLaba1/MovementStrategy/IMoveableObject.cs b/PrLaba1/PrLaba1/MovementStrategy/IMoveableObject.cs new file mode 100644 index 0000000..608d382 --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/IMoveableObject.cs @@ -0,0 +1,23 @@ +namespace PrLaba1.MovementStrategy; +/// +/// Интерфейс для работы с перемещаемым объектом +/// +public interface IMoveableObject +{ + /// + /// Получение координаты объекта + /// + ObjectParameters? GetObjectPosition { get; } + + /// + /// Шаг объекта + /// + int GetStep { get; } + + /// + /// Попытка переместить объект в указанном направлении + /// + /// Направление + /// true - объект перемещен, false - перемещение невозможно + bool TryMoveObject(MovementDirection direction); +} \ No newline at end of file diff --git a/PrLaba1/PrLaba1/MovementStrategy/MoveToBoarder.cs b/PrLaba1/PrLaba1/MovementStrategy/MoveToBoarder.cs new file mode 100644 index 0000000..2e0866d --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/MoveToBoarder.cs @@ -0,0 +1,14 @@ +namespace PrLaba1.MovementStrategy; + +public class MoveToBoarder : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + throw new NotImplementedException(); + } + + protected override void MoveToTarget() + { + throw new NotImplementedException(); + } +} diff --git a/PrLaba1/PrLaba1/MovementStrategy/MoveToCentre.cs b/PrLaba1/PrLaba1/MovementStrategy/MoveToCentre.cs new file mode 100644 index 0000000..e77d724 --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/MoveToCentre.cs @@ -0,0 +1,53 @@ +namespace PrLaba1.MovementStrategy; +/// +/// Стратегия перемещения объекта в центр экрана +/// +public class MoveToCentre : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + + return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && + objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + } + + protected override void MoveToTarget() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + + int diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2; + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + + int diffY = objParams.ObjectMiddleVertical - FieldHeight / 2; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } +} diff --git a/PrLaba1/PrLaba1/MovementStrategy/MoveableLoko.cs b/PrLaba1/PrLaba1/MovementStrategy/MoveableLoko.cs new file mode 100644 index 0000000..4180b1f --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/MoveableLoko.cs @@ -0,0 +1,63 @@ +using PrLaba1.Drawnings; + +namespace PrLaba1.MovementStrategy; +/// +/// Класс-реализация IMoveableObject с использованием DrawningCar +/// +public class MoveableLoko : IMoveableObject +{ + /// + /// Поле-объект класса DrawningLoko или его наследника + /// + private readonly DrawningLoko? _loko = null; + + /// + /// Конструктор + /// + /// Объект класса DrawningCar + public MoveableLoko(DrawningLoko loko) + { + _loko = loko; + } + + public ObjectParameters? GetObjectPosition + { + get + { + if (_loko == null || _loko.EntityLoko == null || !_loko.GetPosX.HasValue || !_loko.GetPosY.HasValue) + { + return null; + } + return new ObjectParameters(_loko.GetPosX.Value, _loko.GetPosY.Value, _loko.GetWidth, _loko.GetHeight); + } + } + + public int GetStep => (int)(_loko?.EntityLoko?.Step ?? 0); + + public bool TryMoveObject(MovementDirection direction) + { + if (_loko == null || _loko.EntityLoko == null) + { + return false; + } + + return _loko.MoveTransport(GetDirectionType(direction)); + } + + /// + /// Конвертация из MovementDirection в DirectionType + /// + /// MovementDirection + /// DirectionType + private static Direction GetDirectionType(MovementDirection direction) + { + return direction switch + { + MovementDirection.Left => Direction.Left, + MovementDirection.Right => Direction.Right, + MovementDirection.Up => Direction.Up, + MovementDirection.Down => Direction.Down, + _ => Direction.Unknow, + }; + } +} diff --git a/PrLaba1/PrLaba1/MovementStrategy/MovementDirection.cs b/PrLaba1/PrLaba1/MovementStrategy/MovementDirection.cs new file mode 100644 index 0000000..12c9a10 --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/MovementDirection.cs @@ -0,0 +1,26 @@ +namespace PrLaba1.MovementStrategy; +/// +/// Направление перемещения +/// +public enum MovementDirection +{ + /// + /// Вверх + /// + Up = 1, + + /// + /// Вниз + /// + Down = 2, + + /// + /// Влево + /// + Left = 3, + + /// + /// Вправо + /// + Right = 4 +} diff --git a/PrLaba1/PrLaba1/MovementStrategy/ObjectParameters.cs b/PrLaba1/PrLaba1/MovementStrategy/ObjectParameters.cs new file mode 100644 index 0000000..be06eac --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/ObjectParameters.cs @@ -0,0 +1,72 @@ +namespace PrLaba1.MovementStrategy; + +/// +/// Параметры-координаты объекта +/// +public class ObjectParameters +{ + /// + /// Координата X + /// + private readonly int _x; + + /// + /// Координата Y + /// + private readonly int _y; + + /// + /// Ширина объекта + /// + private readonly int _width; + + /// + /// Высота объекта + /// + private readonly int _height; + + /// + /// Левая граница + /// + public int LeftBorder => _x; + + /// + /// Верхняя граница + /// + public int TopBorder => _y; + + /// + /// Правая граница + /// + public int RightBorder => _x + _width; + + /// + /// Нижняя граница + /// + public int DownBorder => _y + _height; + + /// + /// Середина объекта + /// + public int ObjectMiddleHorizontal => _x + _width / 2; + + /// + /// Середина объекта + /// + public int ObjectMiddleVertical => _y + _height / 2; + + /// + /// Конструктор + /// + /// Координата X + /// Координата Y + /// Ширина объекта + /// Высота объекта + public ObjectParameters(int x, int y, int width, int height) + { + _x = x; + _y = y; + _width = width; + _height = height; + } +} diff --git a/PrLaba1/PrLaba1/MovementStrategy/StrategyStatus.cs b/PrLaba1/PrLaba1/MovementStrategy/StrategyStatus.cs new file mode 100644 index 0000000..4148952 --- /dev/null +++ b/PrLaba1/PrLaba1/MovementStrategy/StrategyStatus.cs @@ -0,0 +1,22 @@ +namespace PrLaba1.MovementStrategy; +/// +/// Статус выполнения операции перемещения +/// +public enum StrategyStatus +{ + + /// + /// Все готово к началу + /// + NotInit, + + /// + /// Выполняется + /// + InProgress, + + /// + /// Завершено + /// + Finish +}