Лабораторная работа №2

This commit is contained in:
user 2024-03-13 21:03:32 +04:00
parent e1e1990698
commit ad6343c0ba
15 changed files with 814 additions and 158 deletions

View File

@ -0,0 +1,28 @@
namespace ProjectMotorBoat.Drawings;
/// <summary>
/// Направление перемещения
/// </summary>
public enum DirectionType
{
/// <summary>
/// Неизвестное направление
/// </summary>
Unknow = -1,
/// <summary>
/// Вверх
/// </summary>
Up = 1,
/// <summary>
/// Вниз
/// </summary>
Down = 2,
/// <summary>
/// Влево
/// </summary>
Left = 3,
/// <summary>
/// Вправо
/// </summary>
Right = 4
}

View File

@ -1,17 +1,13 @@
using System;
using System.DirectoryServices.ActiveDirectory;
using ProjectMotorBoat.Entities;
namespace ProjectMotorBoat;
namespace ProjectMotorBoat.Drawings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawingMotorBoat
public class DrawingBoat
{
/// <summary>
/// Класс-сущность "Катер"
/// </summary>
public EntityMotorBoat? EntityMotorBoat { get; private set; }
public EntityBoat? EntityBoat { get; protected set; }
/// <summary>
/// Ширина окна
@ -24,46 +20,78 @@ public class DrawingMotorBoat
private int? _pictureHeight;
/// <summary>
/// Левая координата прорисовки катера
/// Левая координата прорисовки лодки
/// </summary>
private int? _startPosX;
protected int? _startPosX;
/// <summary>
/// Верхняя кооридната прорисовки катера
/// Верхняя кооридната прорисовки лодки
/// </summary>
private int? _startPosY;
protected int? _startPosY;
/// <summary>
/// Ширина прорисовки катера
/// Ширина прорисовки лодки
/// </summary>
private readonly int _drawningBoatWidth = 100;
/// <summary>
/// Высота прорисовки катера
/// Высота прорисовки лодки
/// </summary>
private readonly int _drawningBoatHeight = 50;
private readonly int _drawningBoatHeight = 30;
/// <summary>
/// Инициализация свойств
/// Координата X объекта
/// </summary>
/// <param name="speed"></param>
/// <param name="weight"></param>
/// <param name="bodyColor"></param>
/// <param name="additionalColor"></param>
/// <param name="inboardEngine"></param>
/// <param name="oar"></param>
/// <param name="protectiveGlass"></param>
public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool inboardEngine, bool oar, bool protectiveGlass)
public int? GetPosX => _startPosX;
/// <summary>
/// Координата Y объекта
/// </summary>
public int? GetPosY => _startPosY;
/// <summary>
/// Ширина объекта
/// </summary>
public int GetWidth => _drawningBoatWidth;
/// <summary>
/// Высота объекта
/// </summary>
public int GetHeight => _drawningBoatHeight;
/// <summary>
/// Пустой конструктор
/// </summary>
private DrawingBoat()
{
EntityMotorBoat = new EntityMotorBoat();
EntityMotorBoat.Init(speed, weight, bodyColor, additionalColor, inboardEngine, oar, protectiveGlass);
_pictureWidth = null;
_pictureHeight = null;
_startPosX = null;
_startPosY = null;
}
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed"></param>
/// <param name="weight"></param>
/// <param name="bodyColor"></param>
public DrawingBoat(int speed, double weight, Color bodyColor) : this()
{
EntityBoat = new EntityBoat(speed, weight, bodyColor);
}
/// <summary>
/// Конструктор для наследников
/// </summary>
/// <param name="drawningBoatWidth"></param>
/// <param name="drawningBoatHeight"></param>
protected DrawingBoat(int drawningBoatWidth, int drawningBoatHeight) : this()
{
_drawningBoatWidth = drawningBoatWidth;
_drawningBoatHeight = drawningBoatHeight;
}
/// <summary>
/// Установка границ поля
/// </summary>
@ -130,7 +158,7 @@ public class DrawingMotorBoat
/// <returns>true - перемещене выполнено, false - перемещение невозможно</returns>
public bool MoveTransport(DirectionType direction)
{
if (EntityMotorBoat == null || !_startPosX.HasValue || !_startPosY.HasValue)
if (EntityBoat == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return false;
}
@ -139,34 +167,34 @@ public class DrawingMotorBoat
{
//влево
case DirectionType.Left:
if (_startPosX.Value - EntityMotorBoat.Step > 0)
if (_startPosX.Value - EntityBoat.Step > 0)
{
_startPosX -= (int)EntityMotorBoat.Step;
_startPosX -= (int)EntityBoat.Step;
}
return true;
//вверх
case DirectionType.Up:
if (_startPosY.Value - EntityMotorBoat.Step > 0)
if (_startPosY.Value - EntityBoat.Step > 0)
{
_startPosY -= (int)EntityMotorBoat.Step;
_startPosY -= (int)EntityBoat.Step;
}
return true;
// вправо
case DirectionType.Right:
//TODO прописать логику сдвига в право ✔
if (_startPosX.Value + EntityMotorBoat.Step < _pictureWidth - _drawningBoatWidth)
if (_startPosX.Value + EntityBoat.Step < _pictureWidth - _drawningBoatWidth)
{
_startPosX += (int)EntityMotorBoat.Step;
_startPosX += (int)EntityBoat.Step;
}
return true;
//вниз
case DirectionType.Down:
//TODO прописать логику сдвига в низ ✔
if (_startPosY.Value + EntityMotorBoat.Step < _pictureHeight - _drawningBoatHeight)
if (_startPosY.Value + EntityBoat.Step < _pictureHeight - _drawningBoatHeight)
{
_startPosY += (int)EntityMotorBoat.Step;
_startPosY += (int)EntityBoat.Step;
}
return true;
default:
@ -178,96 +206,54 @@ public class DrawingMotorBoat
/// Прорисовка объекта
/// </summary>
/// <param name="g"></param>
public void DrawTransport(Graphics g)
public virtual void DrawTransport(Graphics g)
{
if (EntityMotorBoat == null || !_startPosX.HasValue || !_startPosY.HasValue)
if (EntityBoat == null || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(EntityMotorBoat.AdditionalColor);
Brush br = new SolidBrush(EntityMotorBoat.BodyColor);
Brush br = new SolidBrush(EntityBoat.BodyColor);
// Границы катера
Point[] points =
{
new Point(_startPosX.Value, _startPosY.Value + 10),
new Point(_startPosX.Value + 70, _startPosY.Value + 10),
new Point(_startPosX.Value + 100, _startPosY.Value + 25),
new Point(_startPosX.Value + 70, _startPosY.Value + 40),
new Point(_startPosX.Value, _startPosY.Value + 40),
new Point(_startPosX.Value, _startPosY.Value + 10),
new Point(_startPosX.Value, _startPosY.Value),
new Point(_startPosX.Value + 70, _startPosY.Value),
new Point(_startPosX.Value + 100, _startPosY.Value + 15),
new Point(_startPosX.Value + 70, _startPosY.Value + 30),
new Point(_startPosX.Value, _startPosY.Value + 30),
new Point(_startPosX.Value, _startPosY.Value),
};
g.DrawLines(pen, points);
points = new Point[]
{
new Point(_startPosX.Value + 1, _startPosY.Value + 11),
new Point(_startPosX.Value + 72, _startPosY.Value + 11),
new Point(_startPosX.Value + 99, _startPosY.Value + 25),
new Point(_startPosX.Value + 70, _startPosY.Value + 40),
new Point(_startPosX.Value + 1, _startPosY.Value + 40),
new Point(_startPosX.Value + 1, _startPosY.Value + 11),
new Point(_startPosX.Value + 1, _startPosY.Value + 1),
new Point(_startPosX.Value + 72, _startPosY.Value + 1),
new Point(_startPosX.Value + 99, _startPosY.Value + 15),
new Point(_startPosX.Value + 70, _startPosY.Value + 30),
new Point(_startPosX.Value + 1, _startPosY.Value + 30),
new Point(_startPosX.Value + 1, _startPosY.Value + 1),
};
g.FillPolygon(br, points);
// Палуба
g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 20, 65, 10);
g.DrawRectangle(pen, _startPosX.Value + 10, _startPosY.Value + 15, 55, 20);
g.DrawRectangle(pen, _startPosX.Value + 5, _startPosY.Value + 10, 65, 10);
g.DrawRectangle(pen, _startPosX.Value + 10, _startPosY.Value + 5, 55, 20);
g.FillRectangle(br, _startPosX.Value + 6, _startPosY.Value + 20, 64, 11);
g.FillRectangle(br, _startPosX.Value + 11, _startPosY.Value + 16, 56, 19);
g.FillRectangle(br, _startPosX.Value + 6, _startPosY.Value + 10, 64, 11);
g.FillRectangle(br, _startPosX.Value + 11, _startPosY.Value + 6, 56, 19);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 5, 10, 10);
g.DrawEllipse(pen, _startPosX.Value + 60, _startPosY.Value + 5, 10, 10);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 15, 10, 10);
g.DrawEllipse(pen, _startPosX.Value + 60, _startPosY.Value + 15, 10, 10);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 25, 10, 10);
g.DrawEllipse(pen, _startPosX.Value + 60, _startPosY.Value + 25, 10, 10);
g.FillEllipse(br, _startPosX.Value + 5, _startPosY.Value + 15, 11, 11);
g.FillEllipse(br, _startPosX.Value + 59, _startPosY.Value + 15, 11, 11);
g.FillEllipse(br, _startPosX.Value + 5, _startPosY.Value + 24, 11, 11);
g.FillEllipse(br, _startPosX.Value + 59, _startPosY.Value + 24, 11, 11);
// Мотор в корме
if (EntityMotorBoat.InboardEngine)
{
g.DrawRectangle(pen, _startPosX.Value + 3, _startPosY.Value + 13, 20, 24);
g.FillRectangle(additionalBrush, _startPosX.Value + 4, _startPosY.Value + 14, 19, 23);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 15, 6, 6);
g.DrawEllipse(pen, _startPosX.Value + 14, _startPosY.Value + 15, 6, 6);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 28, 6, 6);
g.DrawEllipse(pen, _startPosX.Value + 14, _startPosY.Value + 28, 6, 6);
g.FillEllipse(additionalBrush, _startPosX.Value + 6, _startPosY.Value + 16, 4, 4);
g.FillEllipse(additionalBrush, _startPosX.Value + 15, _startPosY.Value + 16, 4, 4);
g.FillEllipse(additionalBrush, _startPosX.Value + 6, _startPosY.Value + 29, 4, 4);
g.FillEllipse(additionalBrush, _startPosX.Value + 15, _startPosY.Value + 29, 4, 4);
}
// Вёсла
if (EntityMotorBoat.Oar)
{
g.DrawRectangle(pen, _startPosX.Value + 32, _startPosY.Value + 3, 2, 17);
g.DrawRectangle(pen, _startPosX.Value + 32, _startPosY.Value + 30, 2, 17);
g.FillRectangle(additionalBrush, _startPosX.Value + 33, _startPosY.Value + 3, 1, 17);
g.FillRectangle(additionalBrush, _startPosX.Value + 33, _startPosY.Value + 31, 1, 16);
g.DrawEllipse(pen, _startPosX.Value + 30, _startPosY.Value, 6, 8);
g.DrawEllipse(pen, _startPosX.Value + 30, _startPosY.Value + 42, 6, 8);
g.FillEllipse(additionalBrush, _startPosX.Value + 30, _startPosY.Value, 6, 8);
g.FillEllipse(additionalBrush, _startPosX.Value + 30, _startPosY.Value + 42, 6, 8);
}
// Защитное стекло
if (EntityMotorBoat.ProtectiveGlass)
{
Brush brBlue = new SolidBrush(Color.LightBlue);
g.FillRectangle(brBlue, _startPosX.Value + 45, _startPosY.Value + 20, 25, 11);
g.FillRectangle(brBlue, _startPosX.Value + 45, _startPosY.Value + 16, 17, 19);
g.FillEllipse(brBlue, _startPosX.Value + 59, _startPosY.Value + 15, 11, 11);
g.FillEllipse(brBlue, _startPosX.Value + 59, _startPosY.Value + 24, 11, 11);
}
g.FillEllipse(br, _startPosX.Value + 5, _startPosY.Value + 5, 11, 11);
g.FillEllipse(br, _startPosX.Value + 59, _startPosY.Value + 5, 11, 11);
g.FillEllipse(br, _startPosX.Value + 5, _startPosY.Value + 14, 11, 11);
g.FillEllipse(br, _startPosX.Value + 59, _startPosY.Value + 14, 11, 11);
}
}

View File

@ -0,0 +1,85 @@
using ProjectMotorBoat.Entities;
using System.Drawing;
namespace ProjectMotorBoat.Drawings;
/// <summary>
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
/// </summary>
public class DrawingMotorBoat : DrawingBoat
{
/// <summary>
/// Конструктор
/// </summary>
/// <param name="speed"></param>
/// <param name="weight"></param>
/// <param name="bodyColor"></param>
/// <param name="additionalColor"></param>
/// <param name="inboardEngine"></param>
/// <param name="oar"></param>
/// <param name="protectiveGlass"></param>
public DrawingMotorBoat(int speed, double weight, Color bodyColor, Color additionalColor, bool inboardEngine, bool oar, bool protectiveGlass) : base(100, 50)
{
EntityBoat = new EntityMotorBoat(speed, weight, bodyColor, additionalColor, inboardEngine, oar, protectiveGlass);
}
/// <summary>
/// Прорисовка объекта
/// </summary>
/// <param name="g"></param>
public override void DrawTransport(Graphics g)
{
if (EntityBoat == null || EntityBoat is not EntityMotorBoat motorBoat || !_startPosX.HasValue || !_startPosY.HasValue)
{
return;
}
Pen pen = new(Color.Black);
Brush additionalBrush = new SolidBrush(motorBoat.AdditionalColor);
_startPosY += 10;
base.DrawTransport(g);
_startPosY -= 10;
// Мотор в корме
if (motorBoat.InboardEngine)
{
g.DrawRectangle(pen, _startPosX.Value + 3, _startPosY.Value + 13, 20, 24);
g.FillRectangle(additionalBrush, _startPosX.Value + 4, _startPosY.Value + 14, 19, 23);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 15, 6, 6);
g.DrawEllipse(pen, _startPosX.Value + 14, _startPosY.Value + 15, 6, 6);
g.DrawEllipse(pen, _startPosX.Value + 5, _startPosY.Value + 28, 6, 6);
g.DrawEllipse(pen, _startPosX.Value + 14, _startPosY.Value + 28, 6, 6);
g.FillEllipse(additionalBrush, _startPosX.Value + 6, _startPosY.Value + 16, 4, 4);
g.FillEllipse(additionalBrush, _startPosX.Value + 15, _startPosY.Value + 16, 4, 4);
g.FillEllipse(additionalBrush, _startPosX.Value + 6, _startPosY.Value + 29, 4, 4);
g.FillEllipse(additionalBrush, _startPosX.Value + 15, _startPosY.Value + 29, 4, 4);
}
// Вёсла
if (motorBoat.Oar)
{
g.DrawRectangle(pen, _startPosX.Value + 32, _startPosY.Value + 3, 2, 17);
g.DrawRectangle(pen, _startPosX.Value + 32, _startPosY.Value + 30, 2, 17);
g.FillRectangle(additionalBrush, _startPosX.Value + 33, _startPosY.Value + 3, 1, 17);
g.FillRectangle(additionalBrush, _startPosX.Value + 33, _startPosY.Value + 31, 1, 16);
g.DrawEllipse(pen, _startPosX.Value + 30, _startPosY.Value, 6, 8);
g.DrawEllipse(pen, _startPosX.Value + 30, _startPosY.Value + 42, 6, 8);
g.FillEllipse(additionalBrush, _startPosX.Value + 30, _startPosY.Value, 6, 8);
g.FillEllipse(additionalBrush, _startPosX.Value + 30, _startPosY.Value + 42, 6, 8);
}
// Защитное стекло
if (motorBoat.ProtectiveGlass)
{
Brush brBlue = new SolidBrush(Color.LightBlue);
g.FillRectangle(brBlue, _startPosX.Value + 45, _startPosY.Value + 20, 25, 11);
g.FillRectangle(brBlue, _startPosX.Value + 45, _startPosY.Value + 16, 17, 19);
g.FillEllipse(brBlue, _startPosX.Value + 59, _startPosY.Value + 15, 11, 11);
g.FillEllipse(brBlue, _startPosX.Value + 59, _startPosY.Value + 24, 11, 11);
}
}
}

View File

@ -0,0 +1,40 @@
namespace ProjectMotorBoat.Entities;
/// <summary>
/// Класс-сущность "Лодка"
/// </summary>
public class EntityBoat
{
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary>
/// Шаг перемещения катера
/// </summary>
public double Step => Speed * 100 / Weight;
/// <summary>
/// Конструктор сущности
/// </summary>
/// <param name="speed"></param>
/// <param name="weight"></param>
/// <param name="bodyColor"></param>
public EntityBoat(int speed, double weight, Color bodyColor)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
}
}

View File

@ -1,25 +1,10 @@
namespace ProjectMotorBoat;
namespace ProjectMotorBoat.Entities;
/// <summary>
/// Класс-сущность "Катер"
/// </summary>
public class EntityMotorBoat
public class EntityMotorBoat : EntityBoat
{
/// <summary>
/// Скорость
/// </summary>
public int Speed { get; private set; }
/// <summary>
/// Вес
/// </summary>
public double Weight { get; private set; }
/// <summary>
/// Основной цвет
/// </summary>
public Color BodyColor { get; private set; }
/// <summary>
/// Дополнительный цвет (для опциональных элементов)
/// </summary>
@ -40,10 +25,6 @@ public class EntityMotorBoat
/// </summary>
public bool ProtectiveGlass { get; private set; }
/// <summary>
/// Шаг перемещения катера
/// </summary>
public double Step => Speed * 100 / Weight;
/// <summary>
/// Инициализация полей объекта-класса катера
@ -55,11 +36,8 @@ public class EntityMotorBoat
/// <param name="inboardEngine"></param>
/// <param name="oar"></param>
/// <param name="protectiveGlass"></param>
public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool inboardEngine, bool oar, bool protectiveGlass)
public EntityMotorBoat(int speed, double weight, Color bodyColor, Color additionalColor, bool inboardEngine, bool oar, bool protectiveGlass) : base(speed, weight, bodyColor)
{
Speed = speed;
Weight = weight;
BodyColor = bodyColor;
AdditionalColor = additionalColor;
InboardEngine = inboardEngine;
Oar = oar;

View File

@ -34,6 +34,9 @@
buttonUp = new Button();
buttonRight = new Button();
buttonDown = new Button();
buttonCreateBoat = new Button();
comboBoxStrategy = new ComboBox();
buttonStrategyStep = new Button();
((System.ComponentModel.ISupportInitialize)pictureBoxMotorBoat).BeginInit();
SuspendLayout();
//
@ -52,9 +55,9 @@
buttonCreateMotorBoat.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateMotorBoat.Location = new Point(12, 448);
buttonCreateMotorBoat.Name = "buttonCreateMotorBoat";
buttonCreateMotorBoat.Size = new Size(75, 23);
buttonCreateMotorBoat.Size = new Size(160, 23);
buttonCreateMotorBoat.TabIndex = 1;
buttonCreateMotorBoat.Text = "Создать";
buttonCreateMotorBoat.Text = "Создать моторную лодку";
buttonCreateMotorBoat.UseVisualStyleBackColor = true;
buttonCreateMotorBoat.Click += ButtonCreateMotorBoat_Click;
//
@ -106,11 +109,45 @@
buttonDown.UseVisualStyleBackColor = true;
buttonDown.Click += ButtonMoveMotorBoat_click;
//
// buttonCreateBoat
//
buttonCreateBoat.Anchor = AnchorStyles.Bottom | AnchorStyles.Left;
buttonCreateBoat.Location = new Point(178, 448);
buttonCreateBoat.Name = "buttonCreateBoat";
buttonCreateBoat.Size = new Size(160, 23);
buttonCreateBoat.TabIndex = 6;
buttonCreateBoat.Text = "Создать лодку";
buttonCreateBoat.UseVisualStyleBackColor = true;
buttonCreateBoat.Click += ButtonCreateBoat_Click;
//
// comboBoxStrategy
//
comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList;
comboBoxStrategy.FormattingEnabled = true;
comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" });
comboBoxStrategy.Location = new Point(823, 12);
comboBoxStrategy.Name = "comboBoxStrategy";
comboBoxStrategy.Size = new Size(121, 23);
comboBoxStrategy.TabIndex = 7;
//
// buttonStrategyStep
//
buttonStrategyStep.Location = new Point(869, 41);
buttonStrategyStep.Name = "buttonStrategyStep";
buttonStrategyStep.Size = new Size(75, 23);
buttonStrategyStep.TabIndex = 8;
buttonStrategyStep.Text = "Шаг";
buttonStrategyStep.UseVisualStyleBackColor = true;
buttonStrategyStep.Click += ButtonStrategyStep_Click;
//
// FormMotorBoat
//
AutoScaleDimensions = new SizeF(7F, 15F);
AutoScaleMode = AutoScaleMode.Font;
ClientSize = new Size(956, 483);
Controls.Add(buttonStrategyStep);
Controls.Add(comboBoxStrategy);
Controls.Add(buttonCreateBoat);
Controls.Add(buttonDown);
Controls.Add(buttonRight);
Controls.Add(buttonUp);
@ -132,5 +169,8 @@
private Button buttonUp;
private Button buttonRight;
private Button buttonDown;
private Button buttonCreateBoat;
private ComboBox comboBoxStrategy;
private Button buttonStrategyStep;
}
}

View File

@ -1,4 +1,7 @@
namespace ProjectMotorBoat;
using ProjectMotorBoat.Drawings;
using ProjectMotorBoat.MovementStrategy;
namespace ProjectMotorBoat;
/// <summary>
/// Форма работы с объектом "Катер"
@ -8,7 +11,9 @@ public partial class FormMotorBoat : Form
/// <summary>
/// Поле-объект для прорисовки объекта
/// </summary>
private DrawingMotorBoat? _drawingMotorBoat;
private DrawingBoat? _drawingBoat;
private AbstractStrategy? _strategy;
/// <summary>
/// Конструктор формы
@ -16,6 +21,7 @@ public partial class FormMotorBoat : Form
public FormMotorBoat()
{
InitializeComponent();
_strategy = null;
}
/// <summary>
@ -23,36 +29,60 @@ public partial class FormMotorBoat : Form
/// </summary>
private void Draw()
{
if (_drawingMotorBoat == null)
if (_drawingBoat == null)
{
return;
}
Bitmap bmp = new(pictureBoxMotorBoat.Width, pictureBoxMotorBoat.Height);
Graphics gr = Graphics.FromImage(bmp);
_drawingMotorBoat.DrawTransport(gr);
_drawingBoat.DrawTransport(gr);
pictureBoxMotorBoat.Image = bmp;
}
/// <summary>
/// Обработка нажатия кнопки "Создать"
/// Создание объекта класса-перемещения
/// </summary>
/// <param name="type">Тип создаваемого объекта</param>
private void CreateObject(string type)
{
Random random = new();
switch (type)
{
case nameof(DrawingBoat):
_drawingBoat = new DrawingBoat(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(DrawingMotorBoat):
_drawingBoat = new DrawingMotorBoat(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)), Convert.ToBoolean(random.Next(0, 2)));
break;
default:
return;
}
_drawingBoat.SetPictureSize(pictureBoxMotorBoat.Width, pictureBoxMotorBoat.Height);
_drawingBoat.SetPosition(random.Next(10, 100), random.Next(10, 100));
_strategy = null;
comboBoxStrategy.Enabled = true;
Draw();
}
/// <summary>
/// Обработка нажатия кнопки "Создать моторную лодку"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateMotorBoat_Click(object sender, EventArgs e)
{
Random random = new();
_drawingMotorBoat = new DrawingMotorBoat();
_drawingMotorBoat.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)),
Convert.ToBoolean(random.Next(0, 2)));
_drawingMotorBoat.SetPictureSize(pictureBoxMotorBoat.Width, pictureBoxMotorBoat.Height);
_drawingMotorBoat.SetPosition(random.Next(10, 100), random.Next(10, 100));
private void ButtonCreateMotorBoat_Click(object sender, EventArgs e) => CreateObject(nameof(DrawingMotorBoat));
Draw();
}
/// <summary>
/// Обработка нажатия кнопки "Создать лодку"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonCreateBoat_Click(object sender, EventArgs e) => CreateObject(nameof(DrawingBoat));
/// <summary>
/// Перемещение объекта по форме (нажатие кнопок навигации)
@ -61,7 +91,7 @@ public partial class FormMotorBoat : Form
/// <param name="e"></param>
private void ButtonMoveMotorBoat_click(object sender, EventArgs e)
{
if (_drawingMotorBoat == null)
if (_drawingBoat == null)
{
return;
}
@ -71,16 +101,16 @@ public partial class FormMotorBoat : Form
switch (name)
{
case "buttonUp":
result = _drawingMotorBoat.MoveTransport(DirectionType.Up);
result = _drawingBoat.MoveTransport(DirectionType.Up);
break;
case "buttonDown":
result = _drawingMotorBoat.MoveTransport(DirectionType.Down);
result = _drawingBoat.MoveTransport(DirectionType.Down);
break;
case "buttonLeft":
result = _drawingMotorBoat.MoveTransport(DirectionType.Left);
result = _drawingBoat.MoveTransport(DirectionType.Left);
break;
case "buttonRight":
result = _drawingMotorBoat.MoveTransport(DirectionType.Right);
result = _drawingBoat.MoveTransport(DirectionType.Right);
break;
}
@ -89,4 +119,47 @@ public partial class FormMotorBoat : Form
Draw();
}
}
/// <summary>
/// Обработка нажатия кнопки "Шаг"
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void ButtonStrategyStep_Click(object sender, EventArgs e)
{
if (_drawingBoat == null)
{
return;
}
if (comboBoxStrategy.Enabled)
{
_strategy = comboBoxStrategy.SelectedIndex switch
{
0 => new MoveToCenter(),
1 => new MoveToBorder(),
_ => null,
};
if (_strategy == null)
{
return;
}
_strategy.SetData(new MoveableBoat(_drawingBoat), pictureBoxMotorBoat.Width, pictureBoxMotorBoat.Height);
}
if (_strategy == null)
{
return;
}
comboBoxStrategy.Enabled = false;
_strategy.MakeStep();
Draw();
if (_strategy.GetStatus() == StrategyStatus.Finish)
{
comboBoxStrategy.Enabled = true;
_strategy = null;
}
}
}

View File

@ -0,0 +1,139 @@
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Класс-стратегия перемещения объекта
/// </summary>
public abstract class AbstractStrategy
{
/// <summary>
/// Перемещаемый объект
/// </summary>
private IMoveableObject? _moveableObject;
/// <summary>
/// Статус перемещения
/// </summary>
private StrategyStatus _state = StrategyStatus.NotInit;
/// <summary>
/// Ширина поля
/// </summary>
protected int FieldWidth { get; private set; }
/// <summary>
/// Высота поля
/// </summary>
protected int FieldHeight { get; private set; }
/// <summary>
/// Статус перемещения
/// </summary>
public StrategyStatus GetStatus() { return _state; }
/// <summary>
/// Установка данных
/// </summary>
/// <param name="moveableObject">Перемещаемый объект</param>
/// <param name="width">Ширина поля</param>
/// <param name="height">Высота поля</param>
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;
}
/// <summary>
/// Шаг перемещения
/// </summary>
public void MakeStep()
{
if (_state != StrategyStatus.InProgress)
{
return;
}
if (IsTargetDestinaion())
{
_state = StrategyStatus.Finish;
return;
}
MoveToTarget();
}
/// <summary>
/// Перемещение влево
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveLeft() => MoveTo(MovementDirection.Left);
/// <summary>
/// Перемещение вправо
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveRight() => MoveTo(MovementDirection.Right);
/// <summary>
/// Перемещение вверх
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveUp() => MoveTo(MovementDirection.Up);
/// <summary>
/// Перемещение вниз
/// </summary>
/// <returns>Результат перемещения (true - удалось переместиться, false - неудача)</returns>
protected bool MoveDown() => MoveTo(MovementDirection.Down);
/// <summary>
/// Параметры объекта
/// </summary>
protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition;
/// <summary>
/// Шаг объекта
/// </summary>
/// <returns></returns>
protected int? GetStep()
{
if (_state != StrategyStatus.InProgress)
{
return null;
}
return _moveableObject?.GetStep;
}
/// <summary>
/// Перемещение к цели
/// </summary>
protected abstract void MoveToTarget();
/// <summary>
/// Достигнута ли цель
/// </summary>
/// <returns></returns>
protected abstract bool IsTargetDestinaion();
/// <summary>
/// Попытка перемещения в требуемом направлении
/// </summary>
/// <param name="movementDirection">Направление</param>
/// <returns>Результат попытки (true - удалось переместиться, false - неудача)</returns>
private bool MoveTo(MovementDirection movementDirection)
{
if (_state != StrategyStatus.InProgress)
{
return false;
}
return _moveableObject?.TryMoveObject(movementDirection) ?? false;
}
}

View File

@ -0,0 +1,24 @@
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Интерфейс для работы с перемещаемым объектом
/// </summary>
public interface IMoveableObject
{
/// <summary>
/// Получение координаты объекта
/// </summary>
ObjectParameters? GetObjectPosition { get; }
/// <summary>
/// Шаг объекта
/// </summary>
int GetStep { get; }
/// <summary>
/// Попытка переместить объект в указанном направлении
/// </summary>
/// <param name="direction">Направление</param>
/// <returns>true - объект перемещен, false - перемещение невозможно</returns>
bool TryMoveObject(MovementDirection direction);
}

View File

@ -0,0 +1,51 @@
namespace ProjectMotorBoat.MovementStrategy;
public class MoveToBorder : AbstractStrategy
{
protected override bool IsTargetDestinaion()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return false;
}
return objParams.RightBorder - GetStep() <= FieldWidth && objParams.RightBorder + GetStep() >= FieldWidth &&
objParams.DownBorder - GetStep() <= FieldHeight && objParams.DownBorder + GetStep() >= FieldHeight;
}
protected override void MoveToTarget()
{
ObjectParameters? objParams = GetObjectParameters;
if (objParams == null)
{
return;
}
int diffX = objParams.ObjectMiddleHorizontal - FieldWidth;
if (Math.Abs(diffX) > GetStep())
{
if (diffX > 0)
{
MoveLeft();
}
else
{
MoveRight();
}
}
int diffY = objParams.ObjectMiddleVertical - FieldHeight;
if (Math.Abs(diffY) > GetStep())
{
if (diffY > 0)
{
MoveUp();
}
else
{
MoveDown();
}
}
}
}

View File

@ -0,0 +1,54 @@
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Стратегия перемещения объекта в центр экрана
/// </summary>
public class MoveToCenter : 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();
}
}
}
}

View File

@ -0,0 +1,64 @@
using ProjectMotorBoat.Drawings;
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Класс-реализация IMoveableObject с использованием DrawingBoat
/// </summary>
public class MoveableBoat : IMoveableObject
{
/// <summary>
/// Поле-объект класса DrawingBoat или его наследника
/// </summary>
private readonly DrawingBoat? _boat = null;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="boat">Объект класса DrawingBoat</param>
public MoveableBoat(DrawingBoat boat)
{
_boat = boat;
}
public ObjectParameters? GetObjectPosition
{
get
{
if (_boat == null || _boat.EntityBoat == null || !_boat.GetPosX.HasValue || !_boat.GetPosY.HasValue)
{
return null;
}
return new ObjectParameters(_boat.GetPosX.Value, _boat.GetPosY.Value, _boat.GetWidth, _boat.GetHeight);
}
}
public int GetStep => (int)(_boat?.EntityBoat?.Step ?? 0);
public bool TryMoveObject(MovementDirection direction)
{
if (_boat == null || _boat.EntityBoat == null)
{
return false;
}
return _boat.MoveTransport(GetDirectionType(direction));
}
/// <summary>
/// Конвертация из MovementDirection в DirectionType
/// </summary>
/// <param name="direction">MovementDirection</param>
/// <returns>DirectionType</returns>
private static DirectionType GetDirectionType(MovementDirection direction)
{
return direction switch
{
MovementDirection.Left => DirectionType.Left,
MovementDirection.Right => DirectionType.Right,
MovementDirection.Up => DirectionType.Up,
MovementDirection.Down => DirectionType.Down,
_ => DirectionType.Unknow,
};
}
}

View File

@ -1,9 +1,9 @@
namespace ProjectMotorBoat;
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Направление перемещения
/// </summary>
public enum DirectionType
public enum MovementDirection
{
/// <summary>
/// Вверх

View File

@ -0,0 +1,72 @@
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Параметры-координаты объекта
/// </summary>
public class ObjectParameters
{
/// <summary>
/// Координата X
/// </summary>
private readonly int _x;
/// <summary>
/// Координата Y
/// </summary>
private readonly int _y;
/// <summary>
/// Ширина объекта
/// </summary>
private readonly int _width;
/// <summary>
/// Высота объекта
/// </summary>
private readonly int _height;
/// <summary>
/// Левая граница
/// </summary>
public int LeftBorder => _x;
/// <summary>
/// Верхняя граница
/// </summary>
public int TopBorder => _y;
/// <summary>
/// Правая граница
/// </summary>
public int RightBorder => _x + _width;
/// <summary>
/// Нижняя граница
/// </summary>
public int DownBorder => _y + _height;
/// <summary>
/// Середина объекта
/// </summary>
public int ObjectMiddleHorizontal => _x + _width / 2;
/// <summary>
/// Середина объекта
/// </summary>
public int ObjectMiddleVertical => _y + _height / 2;
/// <summary>
/// Конструктор
/// </summary>
/// <param name="x">Координата X</param>
/// <param name="y">Координата Y</param>
/// <param name="width">Ширина объекта</param>
/// <param name="height">Высота объекта</param>
public ObjectParameters(int x, int y, int width, int height)
{
_x = x;
_y = y;
_width = width;
_height = height;
}
}

View File

@ -0,0 +1,22 @@
namespace ProjectMotorBoat.MovementStrategy;
/// <summary>
/// Статус выполнения операции перемещения
/// </summary>
public enum StrategyStatus
{
/// <summary>
/// Все готово к началу
/// </summary>
NotInit,
/// <summary>
/// Выполняется
/// </summary>
InProgress,
/// <summary>
/// Завершено
/// </summary>
Finish
}