diff --git a/ProjectMonorail/ProjectMonorail/AbstractStrategy.cs b/ProjectMonorail/ProjectMonorail/AbstractStrategy.cs new file mode 100644 index 0000000..dba68d6 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/AbstractStrategy.cs @@ -0,0 +1,141 @@ +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Класс-стратегия перемещения объекта + /// + public abstract class AbstractStrategy + { + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + + /// + /// Статус перемещения + /// + private Status _state = Status.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + + /// + /// Статус перемещения + /// + public Status GetStatus() { return _state; } + + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + public void SetData(IMoveableObject moveableObject, int width, int height) + { + if (moveableObject == null) + { + _state = Status.NotInit; + return; + } + _state = Status.InProgress; + _moveableObject = moveableObject; + FieldWidth = width; + FieldHeight = height; + } + + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != Status.InProgress) + { + return; + } + if (IsTargetDestinaion()) + { + _state = Status.Finish; + return; + } + MoveToTarget(); + } + + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveLeft() => MoveTo(DirectionType.Left); + + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveRight() => MoveTo(DirectionType.Right); + + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveUp() => MoveTo(DirectionType.Up); + + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveDown() => MoveTo(DirectionType.Down); + + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition; + + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != Status.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - неудача) + private bool MoveTo(DirectionType directionType) + { + if (_state != Status.InProgress) + { + return false; + } + if (_moveableObject?.CheckCanMove(directionType) ?? false) + { + _moveableObject.MoveObject(directionType); + return true; + } + return false; + } + } +} diff --git a/ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs b/ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs new file mode 100644 index 0000000..dbfe664 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/DrawingExtendedMonorail.cs @@ -0,0 +1,99 @@ +using ProjectMonorail.Entities; + +namespace ProjectMonorail.DrawingObjects +{ + /// + /// Класс, отвечающий за прорисовку и перемещение объекта-сущности + /// + public class DrawingExtendedMonorail : DrawingMonorail + { + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия магнитной рельсы + /// Признак наличия дополнительной кабины + /// Ширина картинки + /// Высота картинки + public DrawingExtendedMonorail(int speed, double weight, Color mainColor, Color additionalColor, bool magneticRail, + bool extraCabin, int width, int height) : base(speed, weight, mainColor, width, height, 186, 92) + { + if (!magneticRail && !extraCabin) + { + _monorailWidth = 117; + _monorailHeight = 56; + } + if (!magneticRail && extraCabin) + { + _monorailWidth = 183; + _monorailHeight = 56; + } + if (EntityMonorail != null) + { + EntityMonorail = new EntityExtendedMonorail(speed, weight, mainColor, + additionalColor, magneticRail, extraCabin); + } + } + + public override void DrawTransport(Graphics g) + { + if (EntityMonorail is not EntityExtendedMonorail extendedMonorail) + { + return; + } + Pen mainPen = new Pen(Color.Black, 2); + Pen additionalPen = new(Color.Blue); + Brush additionalBrush = new SolidBrush(extendedMonorail.AdditionalColor); + Brush brBlue = new SolidBrush(Color.Blue); + Brush brBlack = new SolidBrush(Color.Black); + Brush brWhite = new SolidBrush(Color.White); + Brush brGray = new SolidBrush(Color.Gray); + + base.DrawTransport(g); + + //магнитная рельса + if (extendedMonorail.MagneticRail) + { + g.DrawRectangle(mainPen, _startPosX + 2, _startPosY + 58, 184, 18); + g.FillRectangle(brGray, _startPosX + 2, _startPosY + 58, 184, 18); + for (int i = 0; i < 4; i++) + { + g.DrawRectangle(mainPen, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15); + g.FillRectangle(brGray, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15); + } + } + + //дополнительная кабина + if (extendedMonorail.ExtraCabin) + { + //корпус дополнительной кабины + g.FillRectangle(additionalBrush, _startPosX + 118, _startPosY + 15, 65, 31); + g.DrawRectangle(mainPen, _startPosX + 118, _startPosY + 15, 65, 31); + g.DrawLine(additionalPen, _startPosX + 118, _startPosY + 31, _startPosX + 183, _startPosY + 31); + + //дверь дополнительной кабины + g.FillRectangle(brBlue, _startPosX + 146, _startPosY + 21, 7, 20); + g.DrawRectangle(mainPen, _startPosX + 146, _startPosY + 21, 7, 20); + + //окна дополнительной кабины + g.FillRectangle(brBlue, _startPosX + 130, _startPosY + 18, 6, 9); + g.DrawRectangle(mainPen, _startPosX + 130, _startPosY + 18, 6, 9); + g.FillRectangle(brBlue, _startPosX + 169, _startPosY + 18, 6, 9); + g.DrawRectangle(mainPen, _startPosX + 169, _startPosY + 18, 6, 9); + + //колеса и тележка дополнительной кабины + g.FillRectangle(brBlack, _startPosX + 126, _startPosY + 47, 15, 6); + g.DrawRectangle(mainPen, _startPosX + 126, _startPosY + 47, 15, 6); + g.FillRectangle(brBlack, _startPosX + 159, _startPosY + 47, 15, 6); + g.DrawRectangle(mainPen, _startPosX + 159, _startPosY + 47, 15, 6); + g.FillEllipse(brWhite, _startPosX + 128, _startPosY + 47, 10, 9); + g.DrawEllipse(mainPen, _startPosX + 128, _startPosY + 47, 10, 9); + g.FillEllipse(brWhite, _startPosX + 161, _startPosY + 47, 10, 9); + g.DrawEllipse(mainPen, _startPosX + 161, _startPosY + 47, 10, 9); + } + } + } +} diff --git a/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs b/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs index 4910ccc..d5a2e5f 100644 --- a/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs +++ b/ProjectMonorail/ProjectMonorail/DrawingMonorail.cs @@ -1,4 +1,6 @@ -namespace ProjectMonorail +using ProjectMonorail.Entities; + +namespace ProjectMonorail.DrawingObjects { /// /// Класс, отвечающий за прорисовку и перемещение объекта-сущности @@ -8,7 +10,7 @@ /// /// Класс-сущность /// - public EntityMonorail? EntityMonorail { get; private set; } + public EntityMonorail? EntityMonorail { get; protected set; } /// /// Ширина окна @@ -23,55 +25,78 @@ /// /// Левая координата прорисовки монорельса /// - private int _startPosX; + protected int _startPosX; /// /// Верхняя координата прорисовки монорельса /// - private int _startPosY; + protected int _startPosY; /// /// Ширина прорисовки монорельса /// - private int _monorailWidth = 117; + protected int _monorailWidth = 117; /// /// Высота прорисовки монорельса /// - private int _monorailHeight = 56; + protected int _monorailHeight = 56; /// - /// Инициализация свойств + /// Координата X объекта + /// + public int GetPosX => _startPosX; + + /// + /// Координата Y объекта + /// + public int GetPosY => _startPosY; + + /// + /// Ширина объекта + /// + public int GetWidth => _monorailWidth; + + /// + /// Высота объекта + /// + public int GetHeight => _monorailHeight; + + /// + /// Конструктор /// /// Скорость /// Вес /// Основной цвет - /// Дополнительный цвет - /// Признак наличия магнитной рельсы - /// Признак наличия дополнительной кабины /// Ширина картинки /// Высота картинки - /// true - объект создан, false - проверка не пройдена, - ///нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color mainColor, Color - additionalColor, bool magneticRail, bool extraCabin, int width, int height) + public DrawingMonorail(int speed, double weight, Color mainColor, int width, int height) { - if (extraCabin) - { - _monorailWidth = 183; - } - if (magneticRail) - { - _monorailWidth = 186; - _monorailHeight = 92; - } - if (width < _monorailWidth || height < _monorailHeight) { return false; } + if (width < _monorailWidth || height < _monorailHeight) { return; } _pictureWidth = width; _pictureHeight = height; - EntityMonorail = new EntityMonorail(); - EntityMonorail.Init(speed, weight, mainColor, additionalColor, - magneticRail, extraCabin); - return true; + EntityMonorail = new EntityMonorail(speed, weight, mainColor); + } + + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + /// Ширина прорисовки монорельса + /// Высота прорисовки монорельса + protected DrawingMonorail(int speed, double weight, Color mainColor, int width, + int height, int monorailWidth, int monorailHeight) + { + if (width < monorailWidth || height < monorailHeight) { return; } + _pictureWidth = width; + _pictureHeight = height; + _monorailWidth = monorailWidth; + _monorailHeight = monorailHeight; + EntityMonorail = new EntityMonorail(speed, weight, mainColor); } /// @@ -88,13 +113,39 @@ _startPosY = y; } + /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityMonorail == null) + { + return false; + } + + return direction switch + { + //влево + DirectionType.Left => _startPosX - EntityMonorail.Step > 0, + //вверх + DirectionType.Up => _startPosY - EntityMonorail.Step > 0, + //вправо + DirectionType.Right => _startPosX + _monorailWidth + EntityMonorail.Step < _pictureWidth, + //вниз + DirectionType.Down => _startPosY + _monorailHeight + EntityMonorail.Step < _pictureHeight, + _ => false + }; + } + /// /// Изменение направления перемещения /// /// Направление public void MoveTransport(DirectionType direction) { - if (EntityMonorail == null) + if (!CanMove(direction) || EntityMonorail == null) { return; } @@ -102,31 +153,19 @@ { //влево case DirectionType.Left: - if (_startPosX - EntityMonorail.Step > 0) - { - _startPosX -= (int)EntityMonorail.Step; - } + _startPosX -= (int)EntityMonorail.Step; break; //вверх case DirectionType.Up: - if (_startPosY - EntityMonorail.Step > 0) - { - _startPosY -= (int)EntityMonorail.Step; - } + _startPosY -= (int)EntityMonorail.Step; break; //вправо case DirectionType.Right: - if (_startPosX + _monorailWidth + EntityMonorail.Step < _pictureWidth) - { - _startPosX += (int)EntityMonorail.Step; - } + _startPosX += (int)EntityMonorail.Step; break; //вниз case DirectionType.Down: - if (_startPosY + _monorailHeight + EntityMonorail.Step < _pictureHeight) - { - _startPosY += (int)EntityMonorail.Step; - } + _startPosY += (int)EntityMonorail.Step; break; } } @@ -135,7 +174,7 @@ /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { if (EntityMonorail == null) { @@ -144,7 +183,6 @@ Pen mainPen = new Pen(Color.Black, 2); Pen additionalPen = new(Color.Blue); Brush mainBrush = new SolidBrush(EntityMonorail.MainColor); - Brush additionalBrush = new SolidBrush(EntityMonorail.AdditionalColor); Brush brBlue = new SolidBrush(Color.Blue); Brush brBlack = new SolidBrush(Color.Black); Brush brWhite = new SolidBrush(Color.White); @@ -190,47 +228,6 @@ //соединение между кабинами g.DrawRectangle(mainPen, _startPosX + 112, _startPosY + 18, 5, 28); g.FillRectangle(brBlack, _startPosX + 112, _startPosY + 18, 5, 28); - - //магнитная рельса - if (EntityMonorail.MagneticRail) - { - g.DrawRectangle(mainPen, _startPosX + 2, _startPosY + 58, 184, 18); - g.FillRectangle(brGray, _startPosX + 2, _startPosY + 58, 184, 18); - for (int i = 0; i < 4; i++) - { - g.DrawRectangle(mainPen, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15); - g.FillRectangle(brGray, _startPosX + 35 + 35 * i, _startPosY + 77, 8, 15); - } - } - - //дополнительная кабина - if (EntityMonorail.ExtraCabin) - { - //корпус дополнительной кабины - g.FillRectangle(mainBrush, _startPosX + 118, _startPosY + 15, 65, 31); - g.DrawRectangle(mainPen, _startPosX + 118, _startPosY + 15, 65, 31); - g.DrawLine(additionalPen, _startPosX + 118, _startPosY + 31, _startPosX + 183, _startPosY + 31); - - //дверь дополнительной кабины - g.FillRectangle(additionalBrush, _startPosX + 146, _startPosY + 21, 7, 20); - g.DrawRectangle(mainPen, _startPosX + 146, _startPosY + 21, 7, 20); - - //окна дополнительной кабины - g.FillRectangle(brBlue, _startPosX + 130, _startPosY + 18, 6, 9); - g.DrawRectangle(mainPen, _startPosX + 130, _startPosY + 18, 6, 9); - g.FillRectangle(brBlue, _startPosX + 169, _startPosY + 18, 6, 9); - g.DrawRectangle(mainPen, _startPosX + 169, _startPosY + 18, 6, 9); - - //колеса и тележка дополнительной кабины - g.FillRectangle(brBlack, _startPosX + 126, _startPosY + 47, 15, 6); - g.DrawRectangle(mainPen, _startPosX + 126, _startPosY + 47, 15, 6); - g.FillRectangle(brBlack, _startPosX + 159, _startPosY + 47, 15, 6); - g.DrawRectangle(mainPen, _startPosX + 159, _startPosY + 47, 15, 6); - g.FillEllipse(brWhite, _startPosX + 128, _startPosY + 47, 10, 9); - g.DrawEllipse(mainPen, _startPosX + 128, _startPosY + 47, 10, 9); - g.FillEllipse(brWhite, _startPosX + 161, _startPosY + 47, 10, 9); - g.DrawEllipse(mainPen, _startPosX + 161, _startPosY + 47, 10, 9); - } } } } diff --git a/ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs b/ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs new file mode 100644 index 0000000..5d5d33e --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/DrawingObjectMonorail.cs @@ -0,0 +1,38 @@ +using ProjectMonorail.DrawingObjects; + +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Реализация интерфейса IMoveableObject для работы с объектом DrawingMonorail (паттерн Adapter) + /// + public class DrawingObjectMonorail : IMoveableObject + { + private readonly DrawingMonorail? _drawingMonorail = null; + + public DrawingObjectMonorail(DrawingMonorail drawingMonorail) + { + _drawingMonorail = drawingMonorail; + } + + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawingMonorail == null || _drawingMonorail.EntityMonorail == null) + { + return null; + } + return new ObjectParameters(_drawingMonorail.GetPosX, _drawingMonorail.GetPosY, + _drawingMonorail.GetWidth, _drawingMonorail.GetHeight); + } + } + + public int GetStep => (int)(_drawingMonorail?.EntityMonorail?.Step ?? 0); + + public bool CheckCanMove(DirectionType direction) => + _drawingMonorail?.CanMove(direction) ?? false; + + public void MoveObject(DirectionType direction) => + _drawingMonorail?.MoveTransport(direction); + } +} diff --git a/ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs b/ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs new file mode 100644 index 0000000..b0540ea --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/EntityExtendedMonorail.cs @@ -0,0 +1,40 @@ +namespace ProjectMonorail.Entities +{ + /// + /// Класс-сущность "Расширенный монорельс" + /// + public class EntityExtendedMonorail : EntityMonorail + { + /// + /// Дополнительный цвет (для опциональных элементов) + /// + public Color AdditionalColor { get; private set; } + + /// + /// Признак (опция) наличия магнитной рельсы + /// + public bool MagneticRail { get; private set; } + + /// + /// Признак (опция) наличия дополнительной кабины + /// + public bool ExtraCabin { get; private set; } + + /// + /// Инициализация полей объекта-класса расширенного монорельса + /// + /// Скорость + /// Вес монорельса + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия магнитной рельсы + /// Признак наличия дополнительной кабины + public EntityExtendedMonorail(int speed, double weight, Color mainColor, Color + additionalColor, bool magneticRail, bool extraCabin) : base(speed, weight, mainColor) + { + AdditionalColor = additionalColor; + MagneticRail = magneticRail; + ExtraCabin = extraCabin; + } + } +} diff --git a/ProjectMonorail/ProjectMonorail/EntityMonorail.cs b/ProjectMonorail/ProjectMonorail/EntityMonorail.cs index 4b99444..fdf2f69 100644 --- a/ProjectMonorail/ProjectMonorail/EntityMonorail.cs +++ b/ProjectMonorail/ProjectMonorail/EntityMonorail.cs @@ -1,5 +1,8 @@ -namespace ProjectMonorail +namespace ProjectMonorail.Entities { + /// + /// Класс-сущность "Монорельс" + /// public class EntityMonorail { /// @@ -17,44 +20,23 @@ /// public Color MainColor { get; private set; } - /// - /// Дополнительный цвет (для опциональных элементов) - /// - public Color AdditionalColor { get; private set; } - - /// - /// Признак (опция) наличия магнитной рельсы - /// - public bool MagneticRail { get; private set; } - - /// - /// Признак (опция) наличия дополнительной кабины - /// - public bool ExtraCabin { get; private set; } - /// /// Шаг перемещения монорельса /// public double Step => (double)Speed * 100 / Weight; /// - /// Инициализация полей объекта-класса монорельса + /// Конструктор с параметрами /// /// Скорость /// Вес монорельса - /// Основной цвет - /// Дополнительный цвет - /// Признак наличия магнитной рельсы - /// Признак наличия дополнительной кабины - public void Init(int speed, double weight, Color mainColor, Color - additionalColor, bool magneticRail, bool extraCabin) + /// Основной цвет + public EntityMonorail(int speed, double weight, Color mainColor) { Speed = speed; Weight = weight; MainColor = mainColor; - AdditionalColor = additionalColor; - MagneticRail = magneticRail; - ExtraCabin = extraCabin; } } } + diff --git a/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs b/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs index 382f7fa..081b234 100644 --- a/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs +++ b/ProjectMonorail/ProjectMonorail/FormMonorail.Designer.cs @@ -28,111 +28,152 @@ /// private void InitializeComponent() { - this.pictureBoxMonorail = new System.Windows.Forms.PictureBox(); - this.buttonCreateMonorail = new System.Windows.Forms.Button(); - this.buttonLeft = new System.Windows.Forms.Button(); - this.buttonDown = new System.Windows.Forms.Button(); - this.buttonRight = new System.Windows.Forms.Button(); - this.buttonUp = new System.Windows.Forms.Button(); - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMonorail)).BeginInit(); - this.SuspendLayout(); + pictureBoxMonorail = new PictureBox(); + buttonCreateExtendedMonorail = new Button(); + buttonLeft = new Button(); + buttonDown = new Button(); + buttonRight = new Button(); + buttonUp = new Button(); + comboBoxStrategy = new ComboBox(); + buttonCreateMonorail = new Button(); + buttonStep = new Button(); + ((System.ComponentModel.ISupportInitialize)pictureBoxMonorail).BeginInit(); + SuspendLayout(); // // pictureBoxMonorail // - this.pictureBoxMonorail.Dock = System.Windows.Forms.DockStyle.Fill; - this.pictureBoxMonorail.Location = new System.Drawing.Point(0, 0); - this.pictureBoxMonorail.Name = "pictureBoxMonorail"; - this.pictureBoxMonorail.Size = new System.Drawing.Size(884, 461); - this.pictureBoxMonorail.SizeMode = System.Windows.Forms.PictureBoxSizeMode.AutoSize; - this.pictureBoxMonorail.TabIndex = 0; - this.pictureBoxMonorail.TabStop = false; + pictureBoxMonorail.Dock = DockStyle.Fill; + pictureBoxMonorail.Location = new Point(0, 0); + pictureBoxMonorail.Name = "pictureBoxMonorail"; + pictureBoxMonorail.Size = new Size(884, 461); + pictureBoxMonorail.SizeMode = PictureBoxSizeMode.AutoSize; + pictureBoxMonorail.TabIndex = 0; + pictureBoxMonorail.TabStop = false; // - // buttonCreateMonorail + // buttonCreateExtendedMonorail // - this.buttonCreateMonorail.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Left))); - this.buttonCreateMonorail.Location = new System.Drawing.Point(12, 419); - this.buttonCreateMonorail.Name = "buttonCreateMonorail"; - this.buttonCreateMonorail.Size = new System.Drawing.Size(75, 23); - this.buttonCreateMonorail.TabIndex = 1; - this.buttonCreateMonorail.Text = "Create"; - this.buttonCreateMonorail.UseVisualStyleBackColor = true; - this.buttonCreateMonorail.Click += new System.EventHandler(this.buttonCreateMonorail_Click); + buttonCreateExtendedMonorail.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateExtendedMonorail.Location = new Point(12, 403); + buttonCreateExtendedMonorail.Name = "buttonCreateExtendedMonorail"; + buttonCreateExtendedMonorail.Size = new Size(140, 39); + buttonCreateExtendedMonorail.TabIndex = 1; + buttonCreateExtendedMonorail.Text = "Create extended monorail"; + buttonCreateExtendedMonorail.UseVisualStyleBackColor = true; + buttonCreateExtendedMonorail.Click += buttonCreateExtendedMonorail_Click; // // buttonLeft // - this.buttonLeft.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonLeft.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowLeft; - this.buttonLeft.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.buttonLeft.Location = new System.Drawing.Point(770, 419); - this.buttonLeft.Name = "buttonLeft"; - this.buttonLeft.Size = new System.Drawing.Size(30, 30); - this.buttonLeft.TabIndex = 2; - this.buttonLeft.UseVisualStyleBackColor = true; - this.buttonLeft.Click += new System.EventHandler(this.buttonMove_Click); + buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonLeft.BackgroundImage = Properties.Resources.arrowLeft; + buttonLeft.BackgroundImageLayout = ImageLayout.Zoom; + buttonLeft.Location = new Point(770, 419); + buttonLeft.Name = "buttonLeft"; + buttonLeft.Size = new Size(30, 30); + buttonLeft.TabIndex = 2; + buttonLeft.UseVisualStyleBackColor = true; + buttonLeft.Click += buttonMove_Click; // // buttonDown // - this.buttonDown.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonDown.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowDown; - this.buttonDown.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.buttonDown.Location = new System.Drawing.Point(806, 419); - this.buttonDown.Name = "buttonDown"; - this.buttonDown.Size = new System.Drawing.Size(30, 30); - this.buttonDown.TabIndex = 3; - this.buttonDown.UseVisualStyleBackColor = true; - this.buttonDown.Click += new System.EventHandler(this.buttonMove_Click); + buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonDown.BackgroundImage = Properties.Resources.arrowDown; + buttonDown.BackgroundImageLayout = ImageLayout.Zoom; + buttonDown.Location = new Point(806, 419); + buttonDown.Name = "buttonDown"; + buttonDown.Size = new Size(30, 30); + buttonDown.TabIndex = 3; + buttonDown.UseVisualStyleBackColor = true; + buttonDown.Click += buttonMove_Click; // // buttonRight // - this.buttonRight.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonRight.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowRight; - this.buttonRight.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.buttonRight.Location = new System.Drawing.Point(842, 419); - this.buttonRight.Name = "buttonRight"; - this.buttonRight.Size = new System.Drawing.Size(30, 30); - this.buttonRight.TabIndex = 4; - this.buttonRight.UseVisualStyleBackColor = true; - this.buttonRight.Click += new System.EventHandler(this.buttonMove_Click); + buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonRight.BackgroundImage = Properties.Resources.arrowRight; + buttonRight.BackgroundImageLayout = ImageLayout.Zoom; + buttonRight.Location = new Point(842, 419); + buttonRight.Name = "buttonRight"; + buttonRight.Size = new Size(30, 30); + buttonRight.TabIndex = 4; + buttonRight.UseVisualStyleBackColor = true; + buttonRight.Click += buttonMove_Click; // // buttonUp // - this.buttonUp.Anchor = ((System.Windows.Forms.AnchorStyles)((System.Windows.Forms.AnchorStyles.Bottom | System.Windows.Forms.AnchorStyles.Right))); - this.buttonUp.BackgroundImage = global::ProjectMonorail.Properties.Resources.arrowUp; - this.buttonUp.BackgroundImageLayout = System.Windows.Forms.ImageLayout.Zoom; - this.buttonUp.Location = new System.Drawing.Point(806, 383); - this.buttonUp.Name = "buttonUp"; - this.buttonUp.Size = new System.Drawing.Size(30, 30); - this.buttonUp.TabIndex = 5; - this.buttonUp.UseVisualStyleBackColor = true; - this.buttonUp.Click += new System.EventHandler(this.buttonMove_Click); + buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonUp.BackgroundImage = Properties.Resources.arrowUp; + buttonUp.BackgroundImageLayout = ImageLayout.Zoom; + buttonUp.Location = new Point(806, 383); + buttonUp.Name = "buttonUp"; + buttonUp.Size = new Size(30, 30); + buttonUp.TabIndex = 5; + buttonUp.UseVisualStyleBackColor = true; + buttonUp.Click += buttonMove_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.Anchor = AnchorStyles.Top | AnchorStyles.Right; + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "Form center", "Form border" }); + comboBoxStrategy.Location = new Point(751, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 6; + // + // buttonCreateMonorail + // + buttonCreateMonorail.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateMonorail.Location = new Point(168, 403); + buttonCreateMonorail.Name = "buttonCreateMonorail"; + buttonCreateMonorail.Size = new Size(140, 39); + buttonCreateMonorail.TabIndex = 7; + buttonCreateMonorail.Text = "Create monorail"; + buttonCreateMonorail.UseVisualStyleBackColor = true; + buttonCreateMonorail.Click += buttonCreateMonorail_Click; + // + // buttonStep + // + buttonStep.Anchor = AnchorStyles.Top | AnchorStyles.Right; + buttonStep.Location = new Point(797, 50); + buttonStep.Name = "buttonStep"; + buttonStep.Size = new Size(75, 28); + buttonStep.TabIndex = 8; + buttonStep.Text = "Step"; + buttonStep.UseVisualStyleBackColor = true; + buttonStep.Click += buttonStep_Click; // // FormMonorail // - this.AutoScaleDimensions = new System.Drawing.SizeF(7F, 15F); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(884, 461); - this.Controls.Add(this.buttonUp); - this.Controls.Add(this.buttonRight); - this.Controls.Add(this.buttonDown); - this.Controls.Add(this.buttonLeft); - this.Controls.Add(this.buttonCreateMonorail); - this.Controls.Add(this.pictureBoxMonorail); - this.Name = "FormMonorail"; - this.StartPosition = System.Windows.Forms.FormStartPosition.CenterScreen; - this.Text = "Monorail"; - ((System.ComponentModel.ISupportInitialize)(this.pictureBoxMonorail)).EndInit(); - this.ResumeLayout(false); - this.PerformLayout(); - + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(884, 461); + Controls.Add(buttonStep); + Controls.Add(buttonCreateMonorail); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonUp); + Controls.Add(buttonRight); + Controls.Add(buttonDown); + Controls.Add(buttonLeft); + Controls.Add(buttonCreateExtendedMonorail); + Controls.Add(pictureBoxMonorail); + Name = "FormMonorail"; + StartPosition = FormStartPosition.CenterScreen; + Text = "Monorail"; + ((System.ComponentModel.ISupportInitialize)pictureBoxMonorail).EndInit(); + ResumeLayout(false); + PerformLayout(); } #endregion private PictureBox pictureBoxMonorail; - private Button buttonCreateMonorail; + private Button buttonCreateExtendedMonorail; private Button buttonLeft; private Button buttonDown; private Button buttonRight; private Button buttonUp; + private ComboBox comboBoxStrategy; + private Button buttonCreateMonorail; + private Button buttonStep; } } \ No newline at end of file diff --git a/ProjectMonorail/ProjectMonorail/FormMonorail.cs b/ProjectMonorail/ProjectMonorail/FormMonorail.cs index a723ad3..2e84ddb 100644 --- a/ProjectMonorail/ProjectMonorail/FormMonorail.cs +++ b/ProjectMonorail/ProjectMonorail/FormMonorail.cs @@ -1,4 +1,7 @@ -namespace ProjectMonorail +using ProjectMonorail.DrawingObjects; +using ProjectMonorail.MovementStrategy; + +namespace ProjectMonorail { /// /// Форма работы с объектом "Монорельс" @@ -10,6 +13,11 @@ /// private DrawingMonorail? _drawingMonorail; + /// + /// Стратегия перемещения + /// + private AbstractStrategy? _abstractStrategy; + /// /// Инициализация формы /// @@ -34,23 +42,36 @@ } /// - /// Обработка нажатия кнопки "Создать" + /// Обработка нажатия кнопки "Создать расширенный монорельс" + /// + /// + /// + private void buttonCreateExtendedMonorail_Click(object sender, EventArgs e) + { + Random random = new(); + _drawingMonorail = new DrawingExtendedMonorail(random.Next(200, 400), 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)), pictureBoxMonorail.Width, pictureBoxMonorail.Height); + _drawingMonorail.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + + /// + /// Обработка нажатия кнопки "Создать монорельс" /// /// /// private void buttonCreateMonorail_Click(object sender, EventArgs e) { Random random = new(); - _drawingMonorail = new DrawingMonorail(); - _drawingMonorail.Init(random.Next(300, 500), 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)), - pictureBoxMonorail.Width, pictureBoxMonorail.Height); + _drawingMonorail = new DrawingMonorail(random.Next(200, 400), random.Next(1000, 3000), Color.FromArgb(random.Next(0, 256), random.Next(0, 256), + random.Next(0, 256)), pictureBoxMonorail.Width, pictureBoxMonorail.Height); _drawingMonorail.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } /// - /// Обработка нажатия кнопок управления движением + /// Изменение положения монорельса /// /// /// @@ -78,5 +99,45 @@ } Draw(); } + + /// + /// Обработка нажатия кнопки "Шаг" + /// + /// + /// + private void buttonStep_Click(object sender, EventArgs e) + { + if (_drawingMonorail == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new DrawingObjectMonorail(_drawingMonorail), pictureBoxMonorail.Width, pictureBoxMonorail.Height); + comboBoxStrategy.Enabled = false; + } + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.MakeStep(); + Draw(); + if (_abstractStrategy.GetStatus() == Status.Finish) + { + comboBoxStrategy.Enabled = true; + _abstractStrategy = null; + } + } } } \ No newline at end of file diff --git a/ProjectMonorail/ProjectMonorail/IMoveableObject.cs b/ProjectMonorail/ProjectMonorail/IMoveableObject.cs new file mode 100644 index 0000000..3470471 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/IMoveableObject.cs @@ -0,0 +1,31 @@ +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Интерфейс для работы с перемещаемым объектом + /// + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + + /// + /// Шаг объекта + /// + int GetStep { get; } + + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(DirectionType direction); + + /// + /// Изменение направления перемещения объекта + /// + /// Направление + void MoveObject(DirectionType direction); + } +} diff --git a/ProjectMonorail/ProjectMonorail/MoveToBorder.cs b/ProjectMonorail/ProjectMonorail/MoveToBorder.cs new file mode 100644 index 0000000..b1f9997 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/MoveToBorder.cs @@ -0,0 +1,46 @@ +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Стратегия перемещения объекта в правый нижний край экрана + /// + public class MoveToBorder : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.RightBorder <= FieldWidth && + objParams.RightBorder + GetStep() >= FieldWidth && + objParams.DownBorder <= FieldHeight && + objParams.DownBorder + GetStep() >= FieldHeight; + } + + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.ObjectMiddleHorizontal - FieldWidth; + if (Math.Abs(diffX) > GetStep()) + { + if (diffX < 0) + { + MoveRight(); + } + } + var diffY = objParams.ObjectMiddleVertical - FieldHeight; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY < 0) + { + MoveDown(); + } + } + } + } +} diff --git a/ProjectMonorail/ProjectMonorail/MoveToCenter.cs b/ProjectMonorail/ProjectMonorail/MoveToCenter.cs new file mode 100644 index 0000000..453a839 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/MoveToCenter.cs @@ -0,0 +1,54 @@ +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Стратегия перемещения объекта в центр экрана + /// + public class MoveToCenter : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.ObjectMiddleHorizontal <= FieldWidth / 2 && + objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && + objParams.ObjectMiddleVertical <= FieldHeight / 2 && + objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + } + + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + var diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2; + if (Math.Abs(diffX) > GetStep()) + { + if (diffX > 0) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + var diffY = objParams.ObjectMiddleVertical - FieldHeight / 2; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } + } +} diff --git a/ProjectMonorail/ProjectMonorail/ObjectParameters.cs b/ProjectMonorail/ProjectMonorail/ObjectParameters.cs new file mode 100644 index 0000000..bc9b7d2 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/ObjectParameters.cs @@ -0,0 +1,61 @@ +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Параметры-координаты объекта + /// + public class ObjectParameters + { + private readonly int _x; + + 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/ProjectMonorail/ProjectMonorail/Status.cs b/ProjectMonorail/ProjectMonorail/Status.cs new file mode 100644 index 0000000..e478c58 --- /dev/null +++ b/ProjectMonorail/ProjectMonorail/Status.cs @@ -0,0 +1,14 @@ +namespace ProjectMonorail.MovementStrategy +{ + /// + /// Статус выполнения операции перемещения + /// + public enum Status + { + NotInit, + + InProgress, + + Finish + } +}