diff --git a/RoadTrain/AbstractStrategy.cs b/RoadTrain/AbstractStrategy.cs new file mode 100644 index 0000000..352a870 --- /dev/null +++ b/RoadTrain/AbstractStrategy.cs @@ -0,0 +1,132 @@ +using RoadTrain.MovementStrategy; +using RoadTrain; +using RoadTrain.DrawningObjects; + +namespace RoadTrain.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/RoadTrain/DrawningObjectTrain.cs b/RoadTrain/DrawningObjectTrain.cs new file mode 100644 index 0000000..2581acc --- /dev/null +++ b/RoadTrain/DrawningObjectTrain.cs @@ -0,0 +1,36 @@ +using RoadTrain.DrawningObjects; +using RoadTrain.MovementStrategy; +using RoadTrain; + +namespace RoadTrain.MovementStrategy +{ + /// + /// Реализация интерфейса IDrawningObject для работы с объектом DrawningCar (паттерн Adapter) +/// +public class DrawningObjectTrain : IMoveableObject + { + private readonly DrawningRoadTrain? _drawningRoadTrain = null; + public DrawningObjectTrain (DrawningRoadTrain drawningRoadTrain) + { + _drawningRoadTrain = drawningRoadTrain; + } + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawningRoadTrain == null || _drawningRoadTrain.EntityRoadTrain == + null) + { + return null; + } + return new ObjectParameters(_drawningRoadTrain.GetPosX, + _drawningRoadTrain.GetPosY, _drawningRoadTrain.GetWidth, _drawningRoadTrain.GetHeight); + } + } + public int GetStep => (int)(_drawningRoadTrain?.EntityRoadTrain?.Step ?? 0); + public bool CheckCanMove(DirectionType direction) => + _drawningRoadTrain?.CanMove(direction) ?? false; + public void MoveObject(DirectionType direction) => + _drawningRoadTrain?.MoveTransport(direction); + } +} diff --git a/RoadTrain/DrawningRoadTrain.cs b/RoadTrain/DrawningRoadTrain.cs index 8f04668..8a261ed 100644 --- a/RoadTrain/DrawningRoadTrain.cs +++ b/RoadTrain/DrawningRoadTrain.cs @@ -3,60 +3,96 @@ using System.Collections.Generic; using System.Linq; using System.Text; using System.Threading.Tasks; +using RoadTrain.Entities; -namespace RoadTrain +namespace RoadTrain.DrawningObjects { public class DrawningRoadTrain { /// /// Класс-сущность /// - public EntityRoadTrain? EntityRoadTrain { get; private set; } + public EntityRoadTrain? EntityRoadTrain { get; protected set; } /// /// Ширина окна /// - private int _pictureWidth; + protected int _pictureWidth; /// /// Высота окна /// - private int _pictureHeight; + protected int _pictureHeight; /// /// Левая координата прорисовки автомобиля /// - private int _startPosX; + protected int _startPosX; /// /// Верхняя кооридната прорисовки автомобиля /// - private int _startPosY; + protected int _startPosY; /// /// Ширина прорисовки автомобиля /// - private readonly int _trainWidth = 70; + protected readonly int _trainWidth = 70; /// /// Высота прорисовки автомобиля /// - private readonly int _trainHeight = 30; + protected readonly int _trainHeight = 30; + /// + /// Координата X объекта + /// + public int GetPosX => _startPosX; + /// + /// Координата Y объекта + /// + public int GetPosY => _startPosY; + /// + /// Ширина объекта + /// + public int GetWidth => _trainWidth; + /// + /// Высота объекта + /// + public int GetHeight => _trainHeight; /// - /// Инициализация свойств + /// Проверка, что объект может переместится по указанному направлению /// - /// Скорость - /// Вес - /// Цвет кузова - /// Дополнительный цвет - /// Признак наличия контейнера для воды - /// Признак наличия щетки - /// Ширина картинки - /// Высота картинки - /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах - public bool Init(EntityRoadTrain entityRoadTrain, int width, int height) + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityRoadTrain == null) + { + return false; + } + return direction switch + { + //влево + DirectionType.Left => _startPosX - EntityRoadTrain.Step > 0, + //вверх + DirectionType.Up => _startPosY - EntityRoadTrain.Step > 0, + // вправо + DirectionType.Right => _startPosX + EntityRoadTrain.Step + _trainWidth < _pictureWidth, + //вниз + DirectionType.Down => _startPosY + EntityRoadTrain.Step + _trainHeight < _pictureHeight + }; + } + + /// + /// Инициализация свойств + /// + /// Скорость + /// Вес + /// Цвет кузова + /// Ширина картинки + /// Высота картинки + /// true - объект создан, false - проверка не пройдена, нельзя создать объект в этих размерах + public DrawningRoadTrain(int speed, double weight, Color bodyColor, int width, int height) { - if (width < _trainWidth) { return false; } - if (height < _trainHeight) { return false; } - _pictureWidth = width; + if (width < _trainWidth) { return; } + if (height < _trainHeight) { return; } + _pictureWidth = width; _pictureHeight = height; - EntityRoadTrain = entityRoadTrain; - - return true; + EntityRoadTrain = new EntityRoadTrain(speed, weight, bodyColor); } /// /// Установка позиции @@ -78,69 +114,44 @@ namespace RoadTrain /// Направление public void MoveTransport(DirectionType direction) { - if (EntityRoadTrain == null) + if (!CanMove(direction) || EntityRoadTrain == null) + { + return; + } + + switch (direction) { - return; - } - switch (direction) - { - //влево - case DirectionType.Left: - if (_startPosX - EntityRoadTrain.Step > 0) - { - _startPosX -= (int)EntityRoadTrain.Step; - } - break; - //вверх - case DirectionType.Up: - if (_startPosY - EntityRoadTrain.Step > 0) - { - _startPosY -= (int)EntityRoadTrain.Step; - } - break; - // вправо - case DirectionType.Right: - if (_startPosX + EntityRoadTrain.Step + _trainWidth < _pictureWidth) - { - _startPosX += (int)EntityRoadTrain.Step; - } - break; - //вниз - case DirectionType.Down: - if (_startPosY + EntityRoadTrain.Step + _trainHeight < _pictureHeight) - { - _startPosY += (int)EntityRoadTrain.Step; - } - break; - } + //влево + case DirectionType.Left: + _startPosX -= (int)EntityRoadTrain.Step; + break; + //вверх + case DirectionType.Up: + _startPosY -= (int)EntityRoadTrain.Step; + break; + // вправо + case DirectionType.Right: + _startPosX += (int)EntityRoadTrain.Step; + break; + //вниз + case DirectionType.Down: + _startPosY += (int)EntityRoadTrain.Step; + break; + } } /// /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { if (EntityRoadTrain == null) { return; } - Pen pen = new(Color.Black); - Brush additionalBrush = new SolidBrush(EntityRoadTrain.AdditionalColor); - //Контейнер с водой - if (EntityRoadTrain.WaterContainer) - { - g.DrawEllipse(pen, _startPosX + 30, _startPosY, 10, 20); - g.FillEllipse(additionalBrush, _startPosX + 30, _startPosY, 10, 20); - - } - if (EntityRoadTrain.SweepingBrush) - { - g.DrawLine(pen, _startPosX + 30, _startPosY + 10, _startPosX + 20, _startPosY + 10); - g.DrawLine(pen, _startPosX + 20, _startPosY + 10, _startPosX + 10, _startPosY + 30); - g.DrawLine(pen, _startPosX + 17, _startPosY + 30, _startPosX + 3, _startPosY + 30); - } Brush br = new SolidBrush(EntityRoadTrain.BodyColor); - g.DrawLine(pen, _startPosX + 20, _startPosY + 20, _startPosX + 70, _startPosY + 20); + Pen pen = new(Color.Black); + g.DrawLine(pen, _startPosX + 20, _startPosY + 20, _startPosX + 70, _startPosY + 20); g.DrawEllipse(pen, _startPosX + 20, _startPosY + 20, 10, 10); g.DrawEllipse(pen, _startPosX + 30, _startPosY + 20, 10, 10); g.DrawEllipse(pen, _startPosX + 60, _startPosY + 20, 10, 10); @@ -152,4 +163,4 @@ namespace RoadTrain g.FillRectangle(br, _startPosX + 60, _startPosY, 10, 20); } } -} +} \ No newline at end of file diff --git a/RoadTrain/DrawningTrain.cs b/RoadTrain/DrawningTrain.cs new file mode 100644 index 0000000..0f45d9f --- /dev/null +++ b/RoadTrain/DrawningTrain.cs @@ -0,0 +1,56 @@ +using RoadTrain.Entities; +using System.Drawing; + +namespace RoadTrain.DrawningObjects +{ + /// + /// Класс, отвечающий за прорисовку и перемещение объекта-сущности + /// + public class DrawningTrain : DrawningRoadTrain + { + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия обвеса + /// Признак наличия антикрыла + /// Ширина картинки + /// Высота картинки + public DrawningTrain(int speed, double weight, Color bodyColor, Color + additionalColor, bool waterContainer, bool sweepingBrush, int width, int height) :base(speed, weight, bodyColor, 70, 30) + { + if (EntityRoadTrain != null) + { + EntityRoadTrain = new EntityTrain(speed, weight, bodyColor, + additionalColor, waterContainer, sweepingBrush); + } + } + public override void DrawTransport(Graphics g) + { + if (EntityRoadTrain is not EntityTrain train) + { + return; + } + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(train.AdditionalColor); + //Контейнер с водой + if (train.WaterContainer) + { + g.DrawEllipse(pen, _startPosX + 30, _startPosY, 10, 20); + g.FillEllipse(additionalBrush, _startPosX + 30, _startPosY, 10, 20); + + } + base.DrawTransport(g); + if (train.SweepingBrush) + { + g.DrawLine(pen, _startPosX + 30, _startPosY + 10, _startPosX + 20, _startPosY + 10); + g.DrawLine(pen, _startPosX + 20, _startPosY + 10, _startPosX + 10, _startPosY + 30); + g.DrawLine(pen, _startPosX + 17, _startPosY + 30, _startPosX + 3, _startPosY + 30); + } + + } + } +} \ No newline at end of file diff --git a/RoadTrain/EntityRoadTrain.cs b/RoadTrain/EntityRoadTrain.cs index ac4557e..3bde5cd 100644 --- a/RoadTrain/EntityRoadTrain.cs +++ b/RoadTrain/EntityRoadTrain.cs @@ -4,37 +4,25 @@ using System.Linq; using System.Text; using System.Threading.Tasks; -namespace RoadTrain +namespace RoadTrain.Entities { public class EntityRoadTrain { /// /// Скорость /// - public int Speed { get; private set; } + public int Speed { get; protected set; } /// /// Вес /// - public double Weight { get; private set; } + public double Weight { get; protected set; } /// /// Основной цвет /// - public Color BodyColor { get; private set; } + public Color BodyColor { get; protected set; } /// /// Дополнительный цвет (для опциональных элементов) /// - public Color AdditionalColor { get; private set; } - /// - /// Признак (опция) наличия контейнера с водой - /// - public bool WaterContainer { get; private set; } - /// - /// Признак (опция) наличия щетки - /// - public bool SweepingBrush { get; private set; } - /// - /// Шаг перемещения поезда - /// public double Step => (double)Speed * 100 / Weight; /// /// Инициализация полей объекта-класса поезда @@ -42,19 +30,12 @@ namespace RoadTrain /// Скорость /// Вес /// Основной цвет - /// Дополнительный цвет - /// Признак наличия контейнера с водой - /// Признак наличия щетки - public void Init(int speed, double weight, Color bodyColor, Color - additionalColor, bool waterContainer, bool sweepingBrush) + + public EntityRoadTrain(int speed, double weight, Color bodyColor) { Speed = speed; Weight = weight; BodyColor = bodyColor; - AdditionalColor = additionalColor; - WaterContainer = waterContainer; - SweepingBrush = sweepingBrush; } - } -} +} \ No newline at end of file diff --git a/RoadTrain/EntityTrain.cs b/RoadTrain/EntityTrain.cs new file mode 100644 index 0000000..629bdb5 --- /dev/null +++ b/RoadTrain/EntityTrain.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RoadTrain.Entities +{ + /// + /// Класс-сущность "Спортивный автомобиль" + /// + public class EntityTrain : EntityRoadTrain + { + /// + /// Дополнительный цвет (для опциональных элементов) + /// + public Color AdditionalColor { get; private set; } + /// + /// Признак (опция) наличия обвеса + /// + public bool WaterContainer { get; private set; } + /// + /// Признак (опция) наличия антикрыла + /// + public bool SweepingBrush { get; private set; } + + /// + /// Инициализация полей объекта-класса спортивного автомобиля + /// + /// Скорость + /// Вес автомобиля + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия контейнера с водой + /// Признак наличия щетки + public EntityTrain(int speed, double weight, Color bodyColor, Color + additionalColor, bool waterContainer, bool sweepingBrush) : base(speed, weight, bodyColor) + { + AdditionalColor = additionalColor; + WaterContainer = waterContainer; + SweepingBrush = sweepingBrush; + } + } + +} diff --git a/RoadTrain/FormRoadTrain.Designer.cs b/RoadTrain/FormRoadTrain.Designer.cs index 6cf71ad..b407a4d 100644 --- a/RoadTrain/FormRoadTrain.Designer.cs +++ b/RoadTrain/FormRoadTrain.Designer.cs @@ -34,18 +34,18 @@ buttonRight = new Button(); buttonDown = new Button(); buttonCreate = new Button(); + button1 = new Button(); + comboBoxStrategy = new ComboBox(); + ButtonStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxRoadTrain).BeginInit(); SuspendLayout(); // // pictureBoxRoadTrain // - pictureBoxRoadTrain.BackgroundImageLayout = ImageLayout.Zoom; - pictureBoxRoadTrain.Dock = DockStyle.Fill; pictureBoxRoadTrain.Location = new Point(0, 0); pictureBoxRoadTrain.Name = "pictureBoxRoadTrain"; - pictureBoxRoadTrain.Size = new Size(685, 362); - pictureBoxRoadTrain.SizeMode = PictureBoxSizeMode.AutoSize; - pictureBoxRoadTrain.TabIndex = 0; + pictureBoxRoadTrain.Size = new Size(685, 361); + pictureBoxRoadTrain.TabIndex = 10; pictureBoxRoadTrain.TabStop = false; // // buttonLeft @@ -53,7 +53,7 @@ buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonLeft.BackgroundImage = Properties.Resources.left; buttonLeft.BackgroundImageLayout = ImageLayout.Zoom; - buttonLeft.Location = new Point(539, 268); + buttonLeft.Location = new Point(533, 269); buttonLeft.Name = "buttonLeft"; buttonLeft.Size = new Size(30, 30); buttonLeft.TabIndex = 2; @@ -65,7 +65,7 @@ buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonUp.BackgroundImage = Properties.Resources.up; buttonUp.BackgroundImageLayout = ImageLayout.Zoom; - buttonUp.Location = new Point(583, 222); + buttonUp.Location = new Point(577, 223); buttonUp.Name = "buttonUp"; buttonUp.Size = new Size(30, 30); buttonUp.TabIndex = 3; @@ -77,7 +77,7 @@ buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonRight.BackgroundImage = Properties.Resources.right; buttonRight.BackgroundImageLayout = ImageLayout.Zoom; - buttonRight.Location = new Point(626, 268); + buttonRight.Location = new Point(620, 269); buttonRight.Name = "buttonRight"; buttonRight.Size = new Size(30, 30); buttonRight.TabIndex = 4; @@ -89,7 +89,7 @@ buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; buttonDown.BackgroundImage = Properties.Resources.down; buttonDown.BackgroundImageLayout = ImageLayout.Zoom; - buttonDown.Location = new Point(583, 314); + buttonDown.Location = new Point(577, 315); buttonDown.Name = "buttonDown"; buttonDown.Size = new Size(30, 30); buttonDown.TabIndex = 5; @@ -99,19 +99,52 @@ // buttonCreate // buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreate.Location = new Point(92, 265); + buttonCreate.Location = new Point(82, 236); buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(75, 23); + buttonCreate.Size = new Size(107, 38); buttonCreate.TabIndex = 6; - buttonCreate.Text = "создать"; + buttonCreate.Text = "создать грузовик"; buttonCreate.UseVisualStyleBackColor = true; buttonCreate.Click += buttonCreate_Click; // + // button1 + // + button1.Location = new Point(82, 289); + button1.Name = "button1"; + button1.Size = new Size(107, 55); + button1.TabIndex = 7; + button1.Text = "создать очистительную машину"; + button1.UseVisualStyleBackColor = true; + button1.Click += button1_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "Центр формы", "Граница формы" }); + comboBoxStrategy.Location = new Point(552, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 8; + // + // ButtonStep + // + ButtonStep.Location = new Point(581, 50); + ButtonStep.Name = "ButtonStep"; + ButtonStep.Size = new Size(75, 23); + ButtonStep.TabIndex = 9; + ButtonStep.Text = "Шаг"; + ButtonStep.UseVisualStyleBackColor = true; + ButtonStep.Click += ButtonStep_Click_1; + // // FormRoadTrain // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(685, 362); + ClientSize = new Size(679, 363); + Controls.Add(ButtonStep); + Controls.Add(comboBoxStrategy); + Controls.Add(button1); Controls.Add(buttonCreate); Controls.Add(buttonDown); Controls.Add(buttonRight); @@ -122,7 +155,6 @@ Text = "FormRoadTrain"; ((System.ComponentModel.ISupportInitialize)pictureBoxRoadTrain).EndInit(); ResumeLayout(false); - PerformLayout(); } #endregion @@ -134,5 +166,8 @@ private Button buttonRight; private Button buttonDown; private Button buttonCreate; + private Button button1; + private ComboBox comboBoxStrategy; + private Button ButtonStep; } } \ No newline at end of file diff --git a/RoadTrain/FormRoadTrain.cs b/RoadTrain/FormRoadTrain.cs index d4ee115..807a737 100644 --- a/RoadTrain/FormRoadTrain.cs +++ b/RoadTrain/FormRoadTrain.cs @@ -1,3 +1,7 @@ +using RoadTrain.MovementStrategy; +using RoadTrain.DrawningObjects; + + namespace RoadTrain { public partial class FormRoadTrain : Form @@ -6,6 +10,8 @@ namespace RoadTrain /// - /// private DrawningRoadTrain? _drawningRoadTrain; + + private AbstractStrategy? _abstractStrategy; /// /// /// @@ -67,25 +73,67 @@ namespace RoadTrain private void buttonCreate_Click(object sender, EventArgs e) { Random random = new(); - _drawningRoadTrain = new DrawningRoadTrain(); - EntityRoadTrain entityRoadTrain = new EntityRoadTrain(); - entityRoadTrain.Init(random.Next(100, 300), - random.Next(1000, 3000), + _drawningRoadTrain = new DrawningRoadTrain(random.Next(100, 300), random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), + random.Next(0, 256)), + pictureBoxRoadTrain.Width, pictureBoxRoadTrain.Height); + _drawningRoadTrain.SetPosition(random.Next(10, 100), + random.Next(10, 100)); + Draw(); + } + + private void button1_Click(object sender, EventArgs e) + { + Random random = new(); + _drawningRoadTrain = new DrawningTrain(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))); - - _drawningRoadTrain.Init(entityRoadTrain, pictureBoxRoadTrain.Width, pictureBoxRoadTrain.Height); - + Convert.ToBoolean(random.Next(0, 2)), + pictureBoxRoadTrain.Width, pictureBoxRoadTrain.Height); _drawningRoadTrain.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } + private void ButtonStep_Click_1(object sender, EventArgs e) + { + if (_drawningRoadTrain == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex + switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new + DrawningObjectTrain(_drawningRoadTrain), pictureBoxRoadTrain.Width, + pictureBoxRoadTrain.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/RoadTrain/FormRoadTrain.resx b/RoadTrain/FormRoadTrain.resx index f298a7b..af32865 100644 --- a/RoadTrain/FormRoadTrain.resx +++ b/RoadTrain/FormRoadTrain.resx @@ -1,4 +1,64 @@ - + + + diff --git a/RoadTrain/IMoveableObject.cs b/RoadTrain/IMoveableObject.cs new file mode 100644 index 0000000..1937800 --- /dev/null +++ b/RoadTrain/IMoveableObject.cs @@ -0,0 +1,32 @@ + +using RoadTrain.MovementStrategy; +using RoadTrain; + +namespace RoadTrain.MovementStrategy +{ + /// + /// Интерфейс для работы с перемещаемым объектом + /// + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + /// + /// Шаг объекта + /// + int GetStep { get; } + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(DirectionType direction); + /// + /// Изменение направления пермещения объекта + /// + /// Направление + void MoveObject(DirectionType direction); + } +} diff --git a/RoadTrain/MoveToBorder.cs b/RoadTrain/MoveToBorder.cs new file mode 100644 index 0000000..b9ddb06 --- /dev/null +++ b/RoadTrain/MoveToBorder.cs @@ -0,0 +1,55 @@ +using RoadTrain.MovementStrategy; + +namespace RoadTrain.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) + { + MoveLeft(); + } + else + { + MoveRight(); + } + } + var diffY = objParams.ObjectMiddleVertical - FieldHeight; + if (Math.Abs(diffY) > GetStep()) + { + if (diffY > 0) + { + MoveUp(); + } + else + { + MoveDown(); + } + } + } + } +} \ No newline at end of file diff --git a/RoadTrain/MoveToCenter.cs b/RoadTrain/MoveToCenter.cs new file mode 100644 index 0000000..ddef685 --- /dev/null +++ b/RoadTrain/MoveToCenter.cs @@ -0,0 +1,55 @@ +using RoadTrain.MovementStrategy; + +namespace RoadTrain.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(); + } + } + } + } +} \ No newline at end of file diff --git a/RoadTrain/ObjectParameters.cs b/RoadTrain/ObjectParameters.cs new file mode 100644 index 0000000..5b75518 --- /dev/null +++ b/RoadTrain/ObjectParameters.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace RoadTrain.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/RoadTrain/Status.cs b/RoadTrain/Status.cs new file mode 100644 index 0000000..ba0d959 --- /dev/null +++ b/RoadTrain/Status.cs @@ -0,0 +1,12 @@ +namespace RoadTrain.MovementStrategy +{ + /// + /// Статус выполнения операции перемещения + /// + public enum Status + { + NotInit, + InProgress, + Finish + } +}