diff --git a/ProjectStormtrooper/ProjectStormtrooper/AbstractStrategy.cs b/ProjectStormtrooper/ProjectStormtrooper/AbstractStrategy.cs new file mode 100644 index 0000000..4ebe813 --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/AbstractStrategy.cs @@ -0,0 +1,132 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Класс-стратегия перемещения объекта + /// + 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/ProjectStormtrooper/ProjectStormtrooper/DrawingObjectPlane.cs b/ProjectStormtrooper/ProjectStormtrooper/DrawingObjectPlane.cs new file mode 100644 index 0000000..f277357 --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/DrawingObjectPlane.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Реализация интерфейса IDrawningObject для работы с объектом DrawningPlane (паттерн Adapter) + /// + public class DrawingObjectPlane : IMoveableObject + { + private readonly DrawingPlane? _drawingPlane = null; + public DrawingObjectPlane(DrawingPlane drawingPlane) + { + _drawingPlane = drawingPlane; + } + + public ObjectParameters? GetObjectPosition + { + get + { + if (_drawingPlane == null || _drawingPlane.EntityPlane == null) + { + return null; + } + return new ObjectParameters(_drawingPlane.GetPosX, _drawingPlane.GetPosY, _drawingPlane.GetWidth, _drawingPlane.GetHeight); + } + } + + public int GetStep => (int)(_drawingPlane?.EntityPlane?.Step ?? 0); + + public bool CheckCanMove(DirectionType direction) => _drawingPlane?.CanMove(direction) ?? false; + + public void MoveObject(DirectionType direction) => _drawingPlane?.MoveTransport(direction); + } +} diff --git a/ProjectStormtrooper/ProjectStormtrooper/DrawingPlane.cs b/ProjectStormtrooper/ProjectStormtrooper/DrawingPlane.cs new file mode 100644 index 0000000..7186346 --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/DrawingPlane.cs @@ -0,0 +1,239 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Класс отвечающий за прорисовку и перемещение объекта-сущности + /// + public class DrawingPlane + { + /// + /// Класс-сущность + /// + public EntityPlane? EntityPlane{ get; protected set; } + /// + /// Ширина окна + /// + private int _pictureWidth; + /// + /// Высота окна + /// + private int _pictureHeight; + /// + /// Левая координата начала прорисовки + /// + protected int _startPosX; + /// + /// Верхняя координата начала прорисовки + /// + protected int _startPosY; + /// + /// Ширина прорисовки + /// + protected readonly int _planeWidth = 110; + /// + /// Высота прорисовки + /// + protected readonly int _planeHeight = 110; + /// + /// Координата X объекта + /// + public int GetPosX => _startPosX; + /// + /// Координата Y объекта + /// + public int GetPosY => _startPosY; + /// + /// Ширина объекта + /// + public int GetWidth => _planeWidth; + /// + /// Высота объекта + /// + public int GetHeight => _planeHeight; + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина картинки + /// Высота картинки + public DrawingPlane(int speed, double weight, Color bodyColor, int width, int height) + { + if (width < _planeWidth && height < _planeHeight) + { + return; + } + _pictureWidth = width; + _pictureHeight = height; + EntityPlane = new EntityPlane(speed, weight, bodyColor); + } + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Ширина окна + /// Высота окна + /// Ширина объекта + /// Высота объекта + protected DrawingPlane(int speed, double weight, Color bodyColor, + int width, int height, int planeWidth, int planeHeight) + { + if (width < planeWidth && height < planeHeight) + { + return; + } + _pictureWidth = width; + _pictureHeight = height; + _planeWidth = planeWidth; + _planeHeight = planeHeight; + EntityPlane = new EntityPlane(speed, weight, bodyColor); + } + /// + /// Проверка, что объект может переместится по указанному направлению + /// + /// Направление + /// true - можно переместится по указанному направлению + public bool CanMove(DirectionType direction) + { + if (EntityPlane == null) + { + return false; + } + return direction switch + { + //вверх + DirectionType.Up => _startPosY - EntityPlane.Step > 0, + //вниз + DirectionType.Down => _startPosY + _planeHeight + EntityPlane.Step < _pictureHeight, + //влево + DirectionType.Left => _startPosX - EntityPlane.Step > 0, + //вправо + DirectionType.Right => _startPosX + _planeWidth + EntityPlane.Step < _pictureWidth, + _ => false, + }; + } + /// + /// Установка позиции + /// + /// Координата X + /// Координата Y + public void SetPosition(int x, int y) + { + if (x < 0) + { + x = 0; + } + else if (x > _pictureWidth - _planeWidth) + { + x = _pictureWidth - _planeWidth; + } + _startPosX = x; + + if (y < 0) + { + y = 0; + } + else if (y > _pictureHeight - _planeHeight) + { + y = _pictureHeight - _planeHeight; + } + _startPosY = y; + } + /// + /// Перемещение объекта + /// + /// Направление перемещения + public void MoveTransport(DirectionType direction) + { + if (!CanMove(direction) || EntityPlane == null) + { + return; + } + switch (direction) + { + // Вверх + case DirectionType.Up: + _startPosY -= (int)EntityPlane.Step; + break; + // Вниз + case DirectionType.Down: + _startPosY += (int)EntityPlane.Step; + break; + // Влево + case DirectionType.Left: + _startPosX -= (int)EntityPlane.Step; + break; + // Вправо + case DirectionType.Right: + _startPosX += (int)EntityPlane.Step; + break; + } + } + /// + /// Прорисовка объекта + /// + /// + public virtual void DrawTransport(Graphics g) + { + if (EntityPlane == null) + { + return; + } + Pen penBlack = new Pen(Color.Black); + Brush brushBlack = new SolidBrush(Color.Black); + Brush brushBodyColor = new SolidBrush(EntityPlane.BodyColor); + + // Высота фюзеляжа + int bodyHeight = _planeHeight / 9; + + // Рисуем нос + + Point[] pointsCockPit = { + new Point(_startPosX, _startPosY + _planeHeight / 2), + new Point(_startPosX + _planeWidth / 8, _startPosY + _planeHeight / 2 - bodyHeight / 2), + new Point(_startPosX + _planeWidth / 8, _startPosY + _planeHeight / 2 + bodyHeight / 2) + }; + + g.FillPolygon(brushBlack, pointsCockPit); + + // Рисуем крылья + + Point[] pointsWings = { + new Point(_startPosX + _planeWidth / 2, _startPosY), + new Point(_startPosX + _planeWidth / 2 + _planeWidth / 15, _startPosY), + new Point(_startPosX + _planeWidth / 2 + _planeWidth / 6, _startPosY + _planeHeight / 2), + new Point(_startPosX + _planeWidth / 2 + _planeWidth / 15, _startPosY + _planeHeight), + new Point(_startPosX + _planeWidth / 2 , _startPosY + _planeHeight) + }; + + g.FillPolygon(brushBodyColor, pointsWings); + g.DrawPolygon(penBlack, pointsWings); + + // Рисуем хвостовое оперение + + Point[] pointsTail = { + new Point(_startPosX + _planeWidth, _startPosY + _planeHeight / 2 - _planeHeight / 3), + new Point(_startPosX + _planeWidth - _planeWidth / 8, _startPosY + _planeHeight / 2 - _planeHeight / 8), + new Point(_startPosX + _planeWidth - _planeWidth / 8, _startPosY + _planeHeight / 2 + _planeHeight / 8), + new Point(_startPosX + _planeWidth, _startPosY + _planeHeight / 2 + _planeHeight / 3) + + }; + + g.FillPolygon(brushBodyColor, pointsTail); + g.DrawPolygon(penBlack, pointsTail); + + // Рисуем фюзеляж + + g.FillRectangle(brushBodyColor, _startPosX + _planeWidth / 8, _startPosY + _planeHeight / 2 - bodyHeight / 2, _planeWidth - _planeWidth / 8, bodyHeight); + g.DrawRectangle(penBlack, _startPosX + _planeWidth / 8, _startPosY + _planeHeight / 2 - bodyHeight / 2, _planeWidth - _planeWidth / 8, bodyHeight); + } + } +} diff --git a/ProjectStormtrooper/ProjectStormtrooper/DrawingStormTrooper.cs b/ProjectStormtrooper/ProjectStormtrooper/DrawingStormTrooper.cs index 76ef983..47dde2b 100644 --- a/ProjectStormtrooper/ProjectStormtrooper/DrawingStormTrooper.cs +++ b/ProjectStormtrooper/ProjectStormtrooper/DrawingStormTrooper.cs @@ -9,38 +9,10 @@ namespace ProjectStormtrooper /// /// Класс отвечающий за прорисовку и перемещение объекта-сущности /// - public class DrawingStormtrooper + public class DrawingStormtrooper : DrawingPlane { /// - /// Класс-сущность - /// - public EntityStormtrooper? EntityStormtrooper { get; private set; } - /// - /// Ширина окна - /// - private int _pictureWidth; - /// - /// Высота окна - /// - private int _pictureHeight; - /// - /// Левая координата начала прорисовки - /// - private int _startPosX; - /// - /// Верхняя координата начала прорисовки - /// - private int _startPosY; - /// - /// Ширина прорисовки - /// - private readonly int _stormtrooperWidth = 110; - /// - /// Высота прорисовки - /// - private readonly int _stormtrooperHeight = 110; - /// - /// Инициализация свойств + /// Конструктор /// /// Скорость /// Вес @@ -50,121 +22,44 @@ namespace ProjectStormtrooper /// Признак наличия бомб /// Ширина картинки /// Высота картинки - /// true - если объект успешно создан, false - проверка не пройдена, - /// т.к. нельзя создать объект в этих размерах - public bool Init(int speed, double weight, Color bodyColor, + public DrawingStormtrooper(int speed, double weight, Color bodyColor, Color additionalColor, bool rockets, bool bombs, - int width, int height) + int width, int height) : base(speed, weight, bodyColor, width, height, 140, 90) { - if (width < _stormtrooperWidth && height < _stormtrooperHeight) + if (EntityPlane != null) { - return false; - } - _pictureWidth = width; - _pictureHeight = height; - EntityStormtrooper = new EntityStormtrooper(); - EntityStormtrooper.Init(speed, weight, bodyColor, additionalColor, rockets, bombs); - return true; - } - /// - /// Установка позиции - /// - /// Координата X - /// Координата Y - public void SetPosition(int x, int y) - { - if (x < 0) - { - x = 0; - } - else if (x > _pictureWidth - _stormtrooperWidth) - { - x = _pictureWidth - _stormtrooperWidth; - } - _startPosX = x; - - if (y < 0) - { - y = 0; - } - else if (y > _pictureHeight - _stormtrooperHeight) - { - y = _pictureHeight - _stormtrooperHeight; - } - _startPosY = y; - } - /// - /// Перемещение объекта - /// - /// Направление перемещения - public void MoveTransport(DirectionType direction) - { - if (EntityStormtrooper == null) - { - return; - } - switch (direction) - { - // Вверх - case DirectionType.Up: - if (_startPosY - EntityStormtrooper.Step >= 0) - { - _startPosY -= (int)EntityStormtrooper.Step; - } - break; - // Вниз - case DirectionType.Down: - if (_startPosY + _stormtrooperHeight + EntityStormtrooper.Step <= _pictureHeight) - { - _startPosY += (int)EntityStormtrooper.Step; - } - break; - // Влево - case DirectionType.Left: - if (_startPosX - EntityStormtrooper.Step >= 0) - { - _startPosX -= (int)EntityStormtrooper.Step; - } - break; - // Вправо - case DirectionType.Right: - if (_startPosX + _stormtrooperWidth + EntityStormtrooper.Step <= _pictureWidth) - { - _startPosX += (int)EntityStormtrooper.Step; - } - break; + EntityPlane = new EntityStormtrooper(speed, weight, bodyColor, additionalColor, rockets, bombs); } } /// /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public override void DrawTransport(Graphics g) { - if (EntityStormtrooper == null) + if (EntityPlane is not EntityStormtrooper stormtrooper) { return; } Pen penBlack = new Pen(Color.Black); Brush brushBlack = new SolidBrush(Color.Black); - Brush brushBodyColor = new SolidBrush(EntityStormtrooper.BodyColor); - Brush brushAdditionalColor = new SolidBrush(EntityStormtrooper.AdditionalColor); + Brush brushAdditionalColor = new SolidBrush(stormtrooper.AdditionalColor); // Высота фюзеляжа - int bodyHeight = _stormtrooperHeight / 9; + int bodyHeight = _planeHeight / 9; // Рисуем бомбы - if (EntityStormtrooper.Bombs) + if (stormtrooper.Bombs) { Point[] pointsBombTail = { - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8 + bodyHeight * 3 - 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 - _stormtrooperHeight / 3 + bodyHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8 + bodyHeight * 3 + 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 - _stormtrooperHeight / 3 + bodyHeight / 2 - 5), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8 + bodyHeight * 3 + 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 - _stormtrooperHeight / 3 + bodyHeight / 2 + 5), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8 + bodyHeight * 3 - 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 - _stormtrooperHeight / 3 + bodyHeight / 2) + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 8 + bodyHeight * 3 - 5, + _startPosY + _planeHeight / 2 - bodyHeight / 2 - _planeHeight / 3 + bodyHeight / 2), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 8 + bodyHeight * 3 + 5, + _startPosY + _planeHeight / 2 - bodyHeight / 2 - _planeHeight / 3 + bodyHeight / 2 - 5), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 8 + bodyHeight * 3 + 5, + _startPosY + _planeHeight / 2 - bodyHeight / 2 - _planeHeight / 3 + bodyHeight / 2 + 5), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 8 + bodyHeight * 3 - 5, + _startPosY + _planeHeight / 2 - bodyHeight / 2 - _planeHeight / 3 + bodyHeight / 2) }; g.FillPolygon(brushAdditionalColor, pointsBombTail); @@ -173,7 +68,7 @@ namespace ProjectStormtrooper for (int i = 0; i < pointsBombTail.Length; i++) { Point p = pointsBombTail[i]; - p.Y = _startPosY + _stormtrooperHeight - (p.Y - _startPosY); + p.Y = _startPosY + _planeHeight - (p.Y - _startPosY); pointsBombTail[i] = p; } @@ -181,30 +76,30 @@ namespace ProjectStormtrooper g.DrawPolygon(penBlack, pointsBombTail); g.FillEllipse(brushAdditionalColor, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 - _stormtrooperHeight / 3, + _startPosX + _planeWidth / 2 - _planeWidth / 8, + _startPosY + _planeHeight / 2 - bodyHeight / 2 - _planeHeight / 3, bodyHeight * 3, bodyHeight); g.DrawEllipse(penBlack, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 - _stormtrooperHeight / 3, + _startPosX + _planeWidth / 2 - _planeWidth / 8, + _startPosY + _planeHeight / 2 - bodyHeight / 2 - _planeHeight / 3, bodyHeight * 3, bodyHeight); g.FillEllipse(brushAdditionalColor, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 + _stormtrooperHeight / 3, + _startPosX + _planeWidth / 2 - _planeWidth / 8, + _startPosY + _planeHeight / 2 - bodyHeight / 2 + _planeHeight / 3, bodyHeight * 3, bodyHeight); g.DrawEllipse(penBlack, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 8, - _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2 + _stormtrooperHeight / 3, + _startPosX + _planeWidth / 2 - _planeWidth / 8, + _startPosY + _planeHeight / 2 - bodyHeight / 2 + _planeHeight / 3, bodyHeight * 3, bodyHeight); } // Рисуем ракеты - if (EntityStormtrooper.Rockets) + if (stormtrooper.Rockets) { int rocketWidth = bodyHeight * 4; int rocketHeight = bodyHeight / 2; @@ -212,21 +107,21 @@ namespace ProjectStormtrooper Brush brushRed = new SolidBrush(Color.Red); Point[] pointsRocketCockPit = { - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5 - rocketHeight, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight) + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 5 - rocketHeight, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight / 2), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 5, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 5, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight) }; Point[] pointsRocketTail = { - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5 - rocketHeight + rocketWidth - 10, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5 + rocketWidth, - _startPosY + _stormtrooperHeight / 2 - bodyHeight * 2 + rocketHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5 + rocketWidth, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight + bodyHeight / 2 - rocketHeight / 2) + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 5 - rocketHeight + rocketWidth - 10, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight / 2), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 5 + rocketWidth, + _startPosY + _planeHeight / 2 - bodyHeight * 2 + rocketHeight / 2), + new Point(_startPosX + _planeWidth / 2 - _planeWidth / 5 + rocketWidth, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2 + rocketHeight + bodyHeight / 2 - rocketHeight / 2) }; g.FillPolygon(brushRed, pointsRocketCockPit); @@ -238,14 +133,14 @@ namespace ProjectStormtrooper for (int i = 0; i < pointsRocketCockPit.Length; i++) { Point p = pointsRocketCockPit[i]; - p.Y = _startPosY + _stormtrooperHeight - (p.Y - _startPosY); + p.Y = _startPosY + _planeHeight - (p.Y - _startPosY); pointsRocketCockPit[i] = p; } for (int i = 0; i < pointsRocketTail.Length; i++) { Point p = pointsRocketTail[i]; - p.Y = _startPosY + _stormtrooperHeight - (p.Y - _startPosY); + p.Y = _startPosY + _planeHeight - (p.Y - _startPosY); pointsRocketTail[i] = p; } @@ -256,68 +151,29 @@ namespace ProjectStormtrooper g.DrawPolygon(penBlack, pointsRocketTail); g.FillRectangle(brushAdditionalColor, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2, + _startPosX + _planeWidth / 2 - _planeWidth / 5, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2, rocketWidth, rocketHeight); g.DrawRectangle(penBlack, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5, - _startPosY + _stormtrooperHeight / 2 - bodyHeight - bodyHeight / 2, + _startPosX + _planeWidth / 2 - _planeWidth / 5, + _startPosY + _planeHeight / 2 - bodyHeight - bodyHeight / 2, rocketWidth, rocketHeight); g.FillRectangle(brushAdditionalColor, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5, - _startPosY + _stormtrooperHeight / 2 + bodyHeight / 2 + bodyHeight / 2, + _startPosX + _planeWidth / 2 - _planeWidth / 5, + _startPosY + _planeHeight / 2 + bodyHeight / 2 + bodyHeight / 2, rocketWidth, rocketHeight); g.DrawRectangle(penBlack, - _startPosX + _stormtrooperWidth / 2 - _stormtrooperWidth / 5, - _startPosY + _stormtrooperHeight / 2 + bodyHeight / 2 + bodyHeight / 2, + _startPosX + _planeWidth / 2 - _planeWidth / 5, + _startPosY + _planeHeight / 2 + bodyHeight / 2 + bodyHeight / 2, rocketWidth, rocketHeight); } - // Рисуем нос - - Point[] pointsCockPit = { - new Point(_startPosX, _startPosY + _stormtrooperHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 8, _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 8, _startPosY + _stormtrooperHeight / 2 + bodyHeight / 2) - }; - - g.FillPolygon(brushBlack, pointsCockPit); - - // Рисуем крылья - - Point[] pointsWings = { - new Point(_startPosX + _stormtrooperWidth / 2, _startPosY), - new Point(_startPosX + _stormtrooperWidth / 2 + _stormtrooperWidth / 15, _startPosY), - new Point(_startPosX + _stormtrooperWidth / 2 + _stormtrooperWidth / 6, _startPosY + _stormtrooperHeight / 2), - new Point(_startPosX + _stormtrooperWidth / 2 + _stormtrooperWidth / 15, _startPosY + _stormtrooperHeight), - new Point(_startPosX + _stormtrooperWidth / 2 , _startPosY + _stormtrooperHeight) - }; - - g.FillPolygon(brushBodyColor, pointsWings); - g.DrawPolygon(penBlack, pointsWings); - - // Рисуем хвостовое оперение - - Point[] pointsTail = { - new Point(_startPosX + _stormtrooperWidth, _startPosY + _stormtrooperHeight / 2 - _stormtrooperHeight / 3), - new Point(_startPosX + _stormtrooperWidth - _stormtrooperWidth / 8, _startPosY + _stormtrooperHeight / 2 - _stormtrooperHeight / 8), - new Point(_startPosX + _stormtrooperWidth - _stormtrooperWidth / 8, _startPosY + _stormtrooperHeight / 2 + _stormtrooperHeight / 8), - new Point(_startPosX + _stormtrooperWidth, _startPosY + _stormtrooperHeight / 2 + _stormtrooperHeight / 3) - - }; - - g.FillPolygon(brushBodyColor, pointsTail); - g.DrawPolygon(penBlack, pointsTail); - - // Рисуем фюзеляж - - g.FillRectangle(brushBodyColor, _startPosX + _stormtrooperWidth / 8, _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2, _stormtrooperWidth - _stormtrooperWidth / 8, bodyHeight); - g.DrawRectangle(penBlack, _startPosX + _stormtrooperWidth / 8, _startPosY + _stormtrooperHeight / 2 - bodyHeight / 2, _stormtrooperWidth - _stormtrooperWidth / 8, bodyHeight); + base.DrawTransport(g); } } } diff --git a/ProjectStormtrooper/ProjectStormtrooper/EntityPlane.cs b/ProjectStormtrooper/ProjectStormtrooper/EntityPlane.cs new file mode 100644 index 0000000..f384c92 --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/EntityPlane.cs @@ -0,0 +1,45 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Net.Sockets; +using System.Text; +using System.Threading.Tasks; +using static System.Reflection.Metadata.BlobBuilder; + +namespace ProjectStormtrooper +{ + /// + /// Класс-сущность "Самолет" + /// + public class EntityPlane + { + /// + /// Скорость + /// + public int Speed { get; private set; } + /// + /// Вес + /// + public double Weight { get; private set; } + /// + /// Основной цвет + /// + public Color BodyColor { get; private set; } + /// + /// Шаг перемещения + /// + public double Step => (double)Speed * 250 / Weight; + /// + /// Конструктор + /// + /// + /// + /// + public EntityPlane(int speed, double weight, Color bodyColor) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + } + } +} diff --git a/ProjectStormtrooper/ProjectStormtrooper/EntityStormtrooper.cs b/ProjectStormtrooper/ProjectStormtrooper/EntityStormtrooper.cs index cc08601..dc7c33e 100644 --- a/ProjectStormtrooper/ProjectStormtrooper/EntityStormtrooper.cs +++ b/ProjectStormtrooper/ProjectStormtrooper/EntityStormtrooper.cs @@ -7,23 +7,11 @@ using System.Threading.Tasks; namespace ProjectStormtrooper { - public class EntityStormtrooper + /// + /// Класс-сущность "Штурмовик" + /// + public class EntityStormtrooper : EntityPlane { - /// - /// Скорость - /// - public int Speed { get; private set; } - /// - /// Вес - /// - public double Weight { get; private set; } - /// - /// Основной цвет - /// - public Color BodyColor { get; private set; } - /// - /// Дополнительный цвет (для опциональных элементов) - /// public Color AdditionalColor { get; private set; } /// /// Признак (опция) наличия ракет @@ -33,24 +21,9 @@ namespace ProjectStormtrooper /// Признак (опция) наличия бомб /// public bool Bombs { get; private set; } - /// - /// Шаг перемещения - /// - public double Step => (double)Speed * 250 / Weight; - /// - /// Инициализация полей объекта-класса штурмовика - /// - /// Скорость - /// Вес - /// Основной цвет - /// Дополнительный цвет - /// Признак наличия ракет - /// Признак наличия бомб - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool rockets, bool bombs) + public EntityStormtrooper(int speed, double weight, Color bodyColor, + Color additionalColor, bool rockets, bool bombs) : base(speed, weight, bodyColor) { - Speed = speed; - Weight = weight; - BodyColor = bodyColor; AdditionalColor = additionalColor; Rockets = rockets; Bombs = bombs; diff --git a/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.Designer.cs b/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.Designer.cs index 9b11491..46e6117 100644 --- a/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.Designer.cs +++ b/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.Designer.cs @@ -29,11 +29,14 @@ private void InitializeComponent() { pictureBoxStormtrooper = new PictureBox(); - buttonCreate = new Button(); + buttonCreateStormtrooper = new Button(); buttonUp = new Button(); buttonDown = new Button(); buttonLeft = new Button(); buttonRight = new Button(); + buttonCreatePlane = new Button(); + comboBoxStrategy = new ComboBox(); + buttonStep = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxStormtrooper).BeginInit(); SuspendLayout(); // @@ -47,16 +50,16 @@ pictureBoxStormtrooper.TabIndex = 0; pictureBoxStormtrooper.TabStop = false; // - // buttonCreate + // buttonCreateStormtrooper // - buttonCreate.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreate.Location = new Point(12, 412); - buttonCreate.Name = "buttonCreate"; - buttonCreate.Size = new Size(94, 29); - buttonCreate.TabIndex = 1; - buttonCreate.Text = "Создать"; - buttonCreate.UseVisualStyleBackColor = true; - buttonCreate.Click += buttonCreate_Click; + buttonCreateStormtrooper.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateStormtrooper.Location = new Point(12, 412); + buttonCreateStormtrooper.Name = "buttonCreateStormtrooper"; + buttonCreateStormtrooper.Size = new Size(201, 29); + buttonCreateStormtrooper.TabIndex = 1; + buttonCreateStormtrooper.Text = "Создать штурмовик"; + buttonCreateStormtrooper.UseVisualStyleBackColor = true; + buttonCreateStormtrooper.Click += buttonCreateStormtrooper_Click; // // buttonUp // @@ -106,16 +109,50 @@ buttonRight.UseVisualStyleBackColor = true; buttonRight.Click += buttonMove_Click; // + // buttonCreatePlane + // + buttonCreatePlane.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreatePlane.Location = new Point(219, 412); + buttonCreatePlane.Name = "buttonCreatePlane"; + buttonCreatePlane.Size = new Size(201, 29); + buttonCreatePlane.TabIndex = 6; + buttonCreatePlane.Text = "Создать самолет"; + buttonCreatePlane.UseVisualStyleBackColor = true; + buttonCreatePlane.Click += buttonCreatePlane_Click; + // + // comboBoxStrategy + // + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "MoveToCenter", "MoveToRightBottom" }); + comboBoxStrategy.Location = new Point(719, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(151, 28); + comboBoxStrategy.TabIndex = 7; + // + // buttonStep + // + buttonStep.Location = new Point(776, 46); + buttonStep.Name = "buttonStep"; + buttonStep.Size = new Size(94, 29); + buttonStep.TabIndex = 8; + buttonStep.Text = "Шаг"; + buttonStep.UseVisualStyleBackColor = true; + buttonStep.Click += buttonStep_Click; + // // FormStormtrooper // AutoScaleDimensions = new SizeF(8F, 20F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(882, 453); + Controls.Add(buttonStep); + Controls.Add(comboBoxStrategy); + Controls.Add(buttonCreatePlane); Controls.Add(buttonRight); Controls.Add(buttonLeft); Controls.Add(buttonDown); Controls.Add(buttonUp); - Controls.Add(buttonCreate); + Controls.Add(buttonCreateStormtrooper); Controls.Add(pictureBoxStormtrooper); Name = "FormStormtrooper"; StartPosition = FormStartPosition.CenterScreen; @@ -128,10 +165,13 @@ #endregion private PictureBox pictureBoxStormtrooper; - private Button buttonCreate; + private Button buttonCreateStormtrooper; private Button buttonUp; private Button buttonDown; private Button buttonLeft; private Button buttonRight; + private Button buttonCreatePlane; + private ComboBox comboBoxStrategy; + private Button buttonStep; } } \ No newline at end of file diff --git a/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.cs b/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.cs index d8b7972..96fc949 100644 --- a/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.cs +++ b/ProjectStormtrooper/ProjectStormtrooper/FormStormtrooper.cs @@ -8,7 +8,8 @@ namespace ProjectStormtrooper /// /// - /// - private DrawingStormtrooper? _drawingStormtrooper; + private DrawingPlane? _drawingPlane; + private AbstractStrategy? _abstractStrategy; /// /// /// @@ -21,25 +22,24 @@ namespace ProjectStormtrooper /// private void Draw() { - if (_drawingStormtrooper == null) + if (_drawingPlane == null) { return; } Bitmap bmp = new(pictureBoxStormtrooper.Width, pictureBoxStormtrooper.Height); Graphics g = Graphics.FromImage(bmp); - _drawingStormtrooper.DrawTransport(g); + _drawingPlane.DrawTransport(g); pictureBoxStormtrooper.Image = bmp; } /// - /// "" + /// " " /// /// /// - private void buttonCreate_Click(object sender, EventArgs e) + private void buttonCreateStormtrooper_Click(object sender, EventArgs e) { Random random = new(); - _drawingStormtrooper = new DrawingStormtrooper(); - _drawingStormtrooper.Init( + _drawingPlane = new DrawingStormtrooper( random.Next(100, 300), random.Next(1000, 3000), Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), @@ -49,7 +49,25 @@ namespace ProjectStormtrooper pictureBoxStormtrooper.Width, pictureBoxStormtrooper.Height ); - _drawingStormtrooper.SetPosition(random.Next(10, 100), random.Next(10, 100)); + _drawingPlane.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + /// + /// " " + /// + /// + /// + private void buttonCreatePlane_Click(object sender, EventArgs e) + { + Random random = new(); + _drawingPlane = new DrawingPlane( + random.Next(100, 300), + random.Next(1000, 3000), + Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)), + pictureBoxStormtrooper.Width, + pictureBoxStormtrooper.Height + ); + _drawingPlane.SetPosition(random.Next(10, 100), random.Next(10, 100)); Draw(); } /// @@ -59,7 +77,7 @@ namespace ProjectStormtrooper /// private void buttonMove_Click(object sender, EventArgs e) { - if (_drawingStormtrooper == null) + if (_drawingPlane == null) { return; } @@ -67,19 +85,57 @@ namespace ProjectStormtrooper switch (buttonName) { case "buttonUp": - _drawingStormtrooper.MoveTransport(DirectionType.Up); + _drawingPlane.MoveTransport(DirectionType.Up); break; case "buttonDown": - _drawingStormtrooper.MoveTransport(DirectionType.Down); + _drawingPlane.MoveTransport(DirectionType.Down); break; case "buttonLeft": - _drawingStormtrooper.MoveTransport(DirectionType.Left); + _drawingPlane.MoveTransport(DirectionType.Left); break; case "buttonRight": - _drawingStormtrooper.MoveTransport(DirectionType.Right); + _drawingPlane.MoveTransport(DirectionType.Right); break; } Draw(); } + /// + /// "" + /// + /// + /// + private void buttonStep_Click(object sender, EventArgs e) + { + if (_drawingPlane == null) + { + return; + } + if (comboBoxStrategy.Enabled) + { + _abstractStrategy = comboBoxStrategy.SelectedIndex switch + { + 0 => new MoveToCenter(), + 1 => new MoveToRightBottom(), + _ => null, + }; + if (_abstractStrategy == null) + { + return; + } + _abstractStrategy.SetData(new DrawingObjectPlane(_drawingPlane), pictureBoxStormtrooper.Width, pictureBoxStormtrooper.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/ProjectStormtrooper/ProjectStormtrooper/IMoveableObject.cs b/ProjectStormtrooper/ProjectStormtrooper/IMoveableObject.cs new file mode 100644 index 0000000..ca329ee --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/IMoveableObject.cs @@ -0,0 +1,34 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Интерфейс для работы с перемещаемым объектом + /// + public interface IMoveableObject + { + /// + /// Получение координаты X объекта + /// + ObjectParameters? GetObjectPosition { get; } + /// + /// Шаг объекта + /// + int GetStep { get; } + /// + /// Проверка, можно ли переместиться по нужному направлению + /// + /// + /// + bool CheckCanMove(DirectionType direction); + /// + /// Изменение направления перемещения объекта + /// + /// Направление + void MoveObject(DirectionType direction); + } +} diff --git a/ProjectStormtrooper/ProjectStormtrooper/MoveToCenter.cs b/ProjectStormtrooper/ProjectStormtrooper/MoveToCenter.cs new file mode 100644 index 0000000..613ca60 --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/MoveToCenter.cs @@ -0,0 +1,58 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Стратегия перемещения объекта в центр экрана + /// + 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/ProjectStormtrooper/ProjectStormtrooper/MoveToRightBottom.cs b/ProjectStormtrooper/ProjectStormtrooper/MoveToRightBottom.cs new file mode 100644 index 0000000..9bc7f3c --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/MoveToRightBottom.cs @@ -0,0 +1,38 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + public class MoveToRightBottom : AbstractStrategy + { + protected override bool IsTargetDestinaion() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return false; + } + return objParams.RightBorder >= FieldWidth - GetStep() && objParams.DownBorder >= FieldHeight - GetStep(); + } + + protected override void MoveToTarget() + { + var objParams = GetObjectParameters; + if (objParams == null) + { + return; + } + if (objParams.RightBorder < FieldWidth - GetStep()) + { + MoveRight(); + } + if (objParams.TopBorder < FieldHeight - GetStep()) + { + MoveDown(); + } + } + } +} diff --git a/ProjectStormtrooper/ProjectStormtrooper/ObjectParameters.cs b/ProjectStormtrooper/ProjectStormtrooper/ObjectParameters.cs new file mode 100644 index 0000000..d64982c --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/ObjectParameters.cs @@ -0,0 +1,57 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Параметры-координаты объекта + /// + 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/ProjectStormtrooper/ProjectStormtrooper/Status.cs b/ProjectStormtrooper/ProjectStormtrooper/Status.cs new file mode 100644 index 0000000..d6556c8 --- /dev/null +++ b/ProjectStormtrooper/ProjectStormtrooper/Status.cs @@ -0,0 +1,18 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectStormtrooper +{ + /// + /// Статус выполнения операции перемещения + /// + public enum Status + { + NotInit, + InProgress, + Finish + } +}