diff --git a/AirBomber/AirBomber.csproj b/AirBomber/AirBomber.csproj
index 13ee123..24f6cce 100644
--- a/AirBomber/AirBomber.csproj
+++ b/AirBomber/AirBomber.csproj
@@ -23,4 +23,8 @@
+
+
+
+
\ No newline at end of file
diff --git a/AirBomber/BomberEntity.cs b/AirBomber/BomberEntity.cs
deleted file mode 100644
index ddf7de2..0000000
--- a/AirBomber/BomberEntity.cs
+++ /dev/null
@@ -1,23 +0,0 @@
-namespace AirBomber
-{
- public class BomberEntity
- {
- public int Speed { get; private set; }
- public double Weight { get; private set; }
- public Color BodyColor { get; private set; }
- public Color AdditionalColor { get; private set; }
- public bool Bombs { get; private set; }
- public bool FuelTanks { get; private set; }
- public double Step => (double)Speed * 100 / Weight * 5 / 2;
-
- public void Init(int Speed, double Weight, Color BodyColor, Color AdditionalColor, bool FuelTanks, bool Bombs)
- {
- this.Speed = Speed;
- this.Weight = Weight;
- this.BodyColor = BodyColor;
- this.AdditionalColor = AdditionalColor;
- this.FuelTanks = FuelTanks;
- this.Bombs = Bombs;
- }
- }
-}
diff --git a/AirBomber/BomberForm.cs b/AirBomber/BomberForm.cs
index 92e4316..7dffb5e 100644
--- a/AirBomber/BomberForm.cs
+++ b/AirBomber/BomberForm.cs
@@ -1,8 +1,10 @@
+using AirBomber.Rendering;
+
namespace AirBomber
{
public partial class BomberForm : Form
{
- private BomberRenderer? _bomberRenderer;
+ private BomberRendererBase? _bomberRenderer;
public BomberForm()
{
@@ -24,7 +26,7 @@ namespace AirBomber
private void ButtonCreate_Click(object sender, EventArgs e)
{
Random random = new Random();
- _bomberRenderer = new BomberRenderer();
+ _bomberRenderer = new BomberRendererBase();
_bomberRenderer.Init(
random.Next(100, 300),
diff --git a/AirBomber/Entities/BomberEntity.cs b/AirBomber/Entities/BomberEntity.cs
new file mode 100644
index 0000000..1eed6a6
--- /dev/null
+++ b/AirBomber/Entities/BomberEntity.cs
@@ -0,0 +1,17 @@
+namespace AirBomber.Entities
+{
+ public class BomberEntity : BomberEntityBase
+ {
+ public Color AdditionalColor { get; private set; }
+ public bool Bombs { get; private set; }
+ public bool FuelTanks { get; private set; }
+
+ public BomberEntity(int Speed, double Weight, Color BodyColor, Color AdditionalColor, bool FuelTanks, bool Bombs)
+ : base(Speed, Weight, BodyColor)
+ {
+ this.AdditionalColor = AdditionalColor;
+ this.FuelTanks = FuelTanks;
+ this.Bombs = Bombs;
+ }
+ }
+}
diff --git a/AirBomber/Entities/BomberEntityBase.cs b/AirBomber/Entities/BomberEntityBase.cs
new file mode 100644
index 0000000..a7f25d8
--- /dev/null
+++ b/AirBomber/Entities/BomberEntityBase.cs
@@ -0,0 +1,17 @@
+namespace AirBomber.Entities
+{
+ public class BomberEntityBase
+ {
+ public int Speed { get; private set; }
+ public double Weight { get; private set; }
+ public Color BodyColor { get; private set; }
+ public double Step => (double)Speed * 100 / Weight * 5 / 2;
+
+ public BomberEntityBase(int Speed, double Weight, Color BodyColor)
+ {
+ this.Speed = Speed;
+ this.Weight = Weight;
+ this.BodyColor = BodyColor;
+ }
+ }
+}
diff --git a/AirBomber/MovementStrategy/AbstractStrategy.cs b/AirBomber/MovementStrategy/AbstractStrategy.cs
new file mode 100644
index 0000000..5dc1b9b
--- /dev/null
+++ b/AirBomber/MovementStrategy/AbstractStrategy.cs
@@ -0,0 +1,76 @@
+namespace AirBomber.MovementStrategy
+{
+ public abstract class AbstractStrategy
+ {
+ private IMovableObject? _movableObject;
+
+ 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(IMovableObject MovableObject, int Width, int Height)
+ {
+ if (MovableObject is null)
+ {
+ _state = Status.NotInit;
+ return;
+ }
+
+ _state = Status.InProgress;
+ _movableObject = MovableObject;
+
+ FieldWidth = Width;
+ FieldHeight = Height;
+ }
+
+ public void MakeStep()
+ {
+ if (_state != Status.InProgress)
+ return;
+
+ if (IsTargetDestination())
+ {
+ _state = Status.Finish;
+ return;
+ }
+
+ MoveToTarget();
+ }
+
+ protected bool MoveLeft() => MoveTo(DirectionType.Left);
+ protected bool MoveRight() => MoveTo(DirectionType.Right);
+ protected bool MoveUp() => MoveTo(DirectionType.Up);
+ protected bool MoveDown() => MoveTo(DirectionType.Down);
+
+ protected ObjectParameters? ObjectParameters => _movableObject?.ObjectPosition;
+
+ protected int? GetStep()
+ {
+ if (_state != Status.InProgress)
+ return null;
+
+ return _movableObject?.Step;
+ }
+
+ protected abstract void MoveToTarget();
+
+ protected abstract bool IsTargetDestination();
+
+ private bool MoveTo(DirectionType DirectionType)
+ {
+ if (_state != Status.InProgress)
+ return false;
+
+ if (_movableObject?.CanMove(DirectionType) ?? false)
+ {
+ _movableObject.MoveObject(DirectionType);
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/AirBomber/DirectionType.cs b/AirBomber/MovementStrategy/DirectionType.cs
similarity index 72%
rename from AirBomber/DirectionType.cs
rename to AirBomber/MovementStrategy/DirectionType.cs
index dfc1798..bac5115 100644
--- a/AirBomber/DirectionType.cs
+++ b/AirBomber/MovementStrategy/DirectionType.cs
@@ -1,4 +1,4 @@
-namespace AirBomber
+namespace AirBomber.MovementStrategy
{
public enum DirectionType
{
diff --git a/AirBomber/MovementStrategy/IMovableObject.cs b/AirBomber/MovementStrategy/IMovableObject.cs
new file mode 100644
index 0000000..160393c
--- /dev/null
+++ b/AirBomber/MovementStrategy/IMovableObject.cs
@@ -0,0 +1,12 @@
+namespace AirBomber.MovementStrategy
+{
+ public interface IMovableObject
+ {
+ ObjectParameters? ObjectPosition { get; }
+ int Step { get; }
+
+ bool CanMove(DirectionType Direction);
+
+ void MoveObject(DirectionType Direction);
+ }
+}
diff --git a/AirBomber/MovementStrategy/MoveToCenterStrategy.cs b/AirBomber/MovementStrategy/MoveToCenterStrategy.cs
new file mode 100644
index 0000000..2192f57
--- /dev/null
+++ b/AirBomber/MovementStrategy/MoveToCenterStrategy.cs
@@ -0,0 +1,44 @@
+namespace AirBomber.MovementStrategy
+{
+ public class MoveToCenterStrategy : AbstractStrategy
+ {
+ protected override bool IsTargetDestination()
+ {
+ ObjectParameters? ObjParams = ObjectParameters;
+ if (ObjParams is null)
+ return false;
+
+ float FieldMiddleHorizontal = FieldWidth / 2;
+ float FieldMiddleVertical = FieldHeight / 2;
+
+ return
+ Math.Abs(ObjParams.ObjectMiddleHorizontal - FieldMiddleHorizontal) < GetStep() &&
+ Math.Abs(ObjParams.ObjectMiddleVertical - FieldMiddleVertical) < GetStep();
+ }
+
+ protected override void MoveToTarget()
+ {
+ ObjectParameters? ObjParams = ObjectParameters;
+ if (ObjParams is null)
+ return;
+
+ float diffX = ObjParams.ObjectMiddleHorizontal - FieldWidth / 2;
+ if (Math.Abs(diffX) > GetStep())
+ {
+ if (diffX > 0)
+ MoveLeft();
+ else
+ MoveRight();
+ }
+
+ float diffY = ObjParams.ObjectMiddleVertical - FieldHeight / 2;
+ if (Math.Abs(diffY) > GetStep())
+ {
+ if (diffY > 0)
+ MoveUp();
+ else
+ MoveDown();
+ }
+ }
+ }
+}
diff --git a/AirBomber/MovementStrategy/MoveToDownRightStrategy.cs b/AirBomber/MovementStrategy/MoveToDownRightStrategy.cs
new file mode 100644
index 0000000..b858fd7
--- /dev/null
+++ b/AirBomber/MovementStrategy/MoveToDownRightStrategy.cs
@@ -0,0 +1,43 @@
+namespace AirBomber.MovementStrategy
+{
+ public class MoveToDownRightStrategy : AbstractStrategy
+ {
+ protected override bool IsTargetDestination()
+ {
+ ObjectParameters? ObjParams = ObjectParameters;
+ if (ObjParams is null)
+ return false;
+
+ return
+ ObjParams.RightBorder <= FieldWidth &&
+ ObjParams.RightBorder + GetStep() >= FieldWidth &&
+ ObjParams.BottomBorder <= FieldHeight &&
+ ObjParams.BottomBorder + GetStep() >= FieldHeight;
+ }
+
+ protected override void MoveToTarget()
+ {
+ ObjectParameters? ObjParams = ObjectParameters;
+ if (ObjParams is null)
+ return;
+
+ float diffX = ObjParams.RightBorder - FieldWidth;
+ if (Math.Abs(diffX) > GetStep())
+ {
+ if (diffX > 0)
+ MoveLeft();
+ else
+ MoveRight();
+ }
+
+ float diffY = ObjParams.BottomBorder - FieldHeight;
+ if (Math.Abs(diffY) > GetStep())
+ {
+ if (diffY > 0)
+ MoveUp();
+ else
+ MoveDown();
+ }
+ }
+ }
+}
diff --git a/AirBomber/MovementStrategy/ObjectEntityRenderer.cs b/AirBomber/MovementStrategy/ObjectEntityRenderer.cs
new file mode 100644
index 0000000..ff1dba7
--- /dev/null
+++ b/AirBomber/MovementStrategy/ObjectEntityRenderer.cs
@@ -0,0 +1,36 @@
+using AirBomber.Rendering;
+
+namespace AirBomber.MovementStrategy
+{
+ public class ObjectEntityRenderer : IMovableObject
+ {
+ private readonly BomberRendererBase? _entityRenderer = null;
+
+ public ObjectEntityRenderer(BomberRendererBase? EntityRenderer)
+ {
+ _entityRenderer = EntityRenderer;
+ }
+
+ public ObjectParameters? ObjectPosition
+ {
+ get
+ {
+ if (_entityRenderer is null || _entityRenderer.EntityBomber is null)
+ return null;
+
+ return new ObjectParameters(
+ _entityRenderer.PosX,
+ _entityRenderer.PosY,
+ _entityRenderer.EntityWidth,
+ _entityRenderer.EntityHeight
+ );
+ }
+ }
+
+ public int Step => (int)(_entityRenderer?.EntityBomber?.Step ?? 0);
+
+ public bool CanMove(DirectionType Direction) => _entityRenderer?.CanMove(Direction) ?? false;
+
+ public void MoveObject(DirectionType Direction) => _entityRenderer?.MoveEntity(Direction);
+ }
+}
diff --git a/AirBomber/MovementStrategy/ObjectParameters.cs b/AirBomber/MovementStrategy/ObjectParameters.cs
new file mode 100644
index 0000000..7720875
--- /dev/null
+++ b/AirBomber/MovementStrategy/ObjectParameters.cs
@@ -0,0 +1,27 @@
+namespace AirBomber.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 BottomBorder => _y + _height;
+
+ public int ObjectMiddleHorizontal => _x + _width / 2;
+ public int ObjectMiddleVertical => _y + _height / 2;
+
+ public ObjectParameters(int X, int Y, int Width, int Height)
+ {
+ _x = X;
+ _y = Y;
+ _width = Width;
+ _height = Height;
+ }
+ }
+}
diff --git a/AirBomber/MovementStrategy/Status.cs b/AirBomber/MovementStrategy/Status.cs
new file mode 100644
index 0000000..041c7ee
--- /dev/null
+++ b/AirBomber/MovementStrategy/Status.cs
@@ -0,0 +1,9 @@
+namespace AirBomber.MovementStrategy
+{
+ public enum Status
+ {
+ NotInit = 1,
+ InProgress,
+ Finish,
+ }
+}
diff --git a/AirBomber/Rendering/BomberRenderer.cs b/AirBomber/Rendering/BomberRenderer.cs
new file mode 100644
index 0000000..f17a167
--- /dev/null
+++ b/AirBomber/Rendering/BomberRenderer.cs
@@ -0,0 +1,55 @@
+using AirBomber.Entities;
+
+namespace AirBomber.Rendering
+{
+ public class BomberRenderer : BomberRendererBase
+ {
+ public BomberRenderer(int Speed, double Weight, Color BodyColor, Color AdditionalColor, bool FuelTanks, bool Bombs, int Width, int Height)
+ : base(Speed, Weight, BodyColor, Width, Height, 200, 200)
+ {
+ if (EntityBomber is not null)
+ EntityBomber = new BomberEntity(Speed, Weight, BodyColor, AdditionalColor, FuelTanks, Bombs);
+ }
+
+ public override void DrawEntity(Graphics g)
+ {
+ if (EntityBomber is not BomberEntity DerivedEntityBomber)
+ return;
+
+ base.DrawEntity(g);
+
+ Brush AdditionalBrush = new SolidBrush(DerivedEntityBomber.AdditionalColor);
+
+ /** Отрисовка дополнительных элементов */
+ if (DerivedEntityBomber.FuelTanks)
+ {
+ Point[] LeftGasTank = {
+ new Point(_startPosX + 50, _startPosY + 85),
+ new Point(_startPosX + 75, _startPosY + 85),
+ new Point(_startPosX + 75, _startPosY + 70),
+ new Point(_startPosX + 50, _startPosY + 70),
+ };
+ g.FillPolygon(AdditionalBrush, LeftGasTank);
+
+ Point[] RightGasTank = {
+ new Point(_startPosX + 50, _startPosY + 115),
+ new Point(_startPosX + 75, _startPosY + 115),
+ new Point(_startPosX + 75, _startPosY + 130),
+ new Point(_startPosX + 50, _startPosY + 130),
+ };
+ g.FillPolygon(AdditionalBrush, RightGasTank);
+ }
+
+ if (DerivedEntityBomber.Bombs)
+ {
+ Point LeftBombStartXY = new Point(_startPosX + 110, _startPosY + 115);
+ Size LeftBombSize = new Size(50, 25);
+ g.FillEllipse(AdditionalBrush, new Rectangle(LeftBombStartXY, LeftBombSize));
+
+ Point RightBombStartXY = new Point(_startPosX + 110, _startPosY + 60);
+ Size RightBombSize = new Size(50, 25);
+ g.FillEllipse(AdditionalBrush, new Rectangle(RightBombStartXY, RightBombSize));
+ }
+ }
+ }
+}
diff --git a/AirBomber/BomberRenderer.cs b/AirBomber/Rendering/BomberRendererBase.cs
similarity index 50%
rename from AirBomber/BomberRenderer.cs
rename to AirBomber/Rendering/BomberRendererBase.cs
index e2a7ef0..ae5ceb0 100644
--- a/AirBomber/BomberRenderer.cs
+++ b/AirBomber/Rendering/BomberRendererBase.cs
@@ -1,33 +1,53 @@
-namespace AirBomber
+using AirBomber.Entities;
+using AirBomber.MovementStrategy;
+
+namespace AirBomber.Rendering
{
- public class BomberRenderer
+ public class BomberRendererBase
{
///
/// Класс, отвечающий за прорисовку и перемещение объекта-сущности
///
- public BomberEntity? EntityBomber { get; private set; }
+ public BomberEntityBase? EntityBomber { get; protected set; }
private int _pictureWidth;
private int _pictureHeight;
- private int _startPosX;
- private int _startPosY;
+ protected int _startPosX;
+ protected int _startPosY;
- private readonly int _bomberWidth = 200;
- private readonly int _bomberHeight = 200;
+ protected readonly int _bomberWidth = 200;
+ protected readonly int _bomberHeight = 200;
- public bool Init(int Speed, double Weight, Color BodyColor, Color AdditionalColor, bool FuelTanks, bool Bombs, int Width, int Height)
+ public int PosX => _startPosX;
+ public int PosY => _startPosY;
+
+ public int EntityWidth => _bomberWidth;
+ public int EntityHeight => _bomberHeight;
+
+ public BomberRendererBase(int Speed, double Weight, Color BodyColor, int Width, int Height)
{
if (Width < _bomberWidth || Height < _bomberHeight)
- return false;
+ return;
_pictureWidth = Width;
_pictureHeight = Height;
- EntityBomber = new BomberEntity();
- EntityBomber.Init(Speed, Weight, BodyColor, AdditionalColor, FuelTanks, Bombs);
+ EntityBomber = new BomberEntityBase(Speed, Weight, BodyColor);
+ }
- return true;
+ public BomberRendererBase(int Speed, double Weight, Color BodyColor, int Width, int Height, int EntityWidth, int EntityHeight)
+ {
+ if (Width < _bomberWidth || Height < _bomberHeight)
+ return;
+
+ _pictureWidth = Width;
+ _pictureHeight = Height;
+
+ _bomberWidth = EntityWidth;
+ _bomberHeight = EntityHeight;
+
+ EntityBomber = new BomberEntityBase(Speed, Weight, BodyColor);
}
public void SetPosition(int x, int y)
@@ -39,7 +59,7 @@
x = 0;
else if (x + _bomberWidth > _pictureWidth)
x = _pictureWidth - _bomberWidth;
-
+
_startPosX = x;
if (y < 0)
@@ -50,56 +70,63 @@
_startPosY = y;
}
+ public bool CanMove(DirectionType direction)
+ {
+ if (EntityBomber is null)
+ return false;
+
+ return direction switch
+ {
+ DirectionType.Left => _startPosX - EntityBomber.Step > 0,
+ DirectionType.Up => _startPosY - EntityBomber.Step > 0,
+ DirectionType.Right => _startPosX + _bomberWidth + EntityBomber.Step <= _pictureWidth,
+ DirectionType.Down => _startPosY + _bomberHeight + EntityBomber.Step <= _pictureHeight,
+
+ _ => false,
+ };
+ }
+
public void MoveEntity(DirectionType Direction)
{
- if (EntityBomber == null)
+ if (EntityBomber == null || !CanMove(Direction))
return;
switch (Direction)
{
- case DirectionType.Up:
- if (_startPosY - EntityBomber.Step > 0)
- _startPosY -= (int)EntityBomber.Step;
-
- break;
-
- case DirectionType.Down:
- if (_startPosY + _bomberHeight + EntityBomber.Step <= _pictureHeight)
- _startPosY += (int)EntityBomber.Step;
-
- break;
-
case DirectionType.Left:
- if (_startPosX - EntityBomber.Step > 0)
- _startPosX -= (int)EntityBomber.Step;
+ _startPosX -= (int)EntityBomber.Step;
+ break;
+ case DirectionType.Up:
+ _startPosY -= (int)EntityBomber.Step;
break;
case DirectionType.Right:
- if (_startPosX + _bomberWidth + EntityBomber.Step <= _pictureWidth)
- _startPosX += (int)EntityBomber.Step;
+ _startPosX += (int)EntityBomber.Step;
+ break;
+ case DirectionType.Down:
+ _startPosY += (int)EntityBomber.Step;
break;
}
}
-
- public void DrawEntity(Graphics g)
+
+ public virtual void DrawEntity(Graphics g)
{
if (EntityBomber == null)
return;
- Pen pen = new Pen(EntityBomber.BodyColor);
+ Pen Pen = new Pen(EntityBomber.BodyColor);
Brush Brush = new SolidBrush(EntityBomber.BodyColor);
- Brush AdditionalBrush = new SolidBrush(EntityBomber.AdditionalColor);
/** Отрисовка основной части */
Point[] LeftWing = {
new Point(_startPosX + 90, _startPosY),
- new Point(_startPosX + 100, _startPosY),
- new Point(_startPosX + 108, _startPosY + 85),
- new Point(_startPosX + 90, _startPosY + 85),
+ new Point(_startPosX + 100, _startPosY),
+ new Point(_startPosX + 108, _startPosY + 85),
+ new Point(_startPosX + 90, _startPosY + 85),
};
- g.DrawPolygon(pen, LeftWing);
+ g.DrawPolygon(Pen, LeftWing);
Point[] RightWing = {
new Point(_startPosX + 90, _startPosY + 200),
@@ -107,7 +134,7 @@
new Point(_startPosX + 108, _startPosY + 115),
new Point(_startPosX + 90, _startPosY + 115),
};
- g.DrawPolygon(pen, RightWing);
+ g.DrawPolygon(Pen, RightWing);
Point[] Body = {
new Point(_startPosX + 35, _startPosY + 85),
@@ -115,7 +142,7 @@
new Point(_startPosX + 200, _startPosY + 115),
new Point(_startPosX + 35, _startPosY + 115),
};
- g.DrawPolygon(pen, Body);
+ g.DrawPolygon(Pen, Body);
Point[] Nose = {
new Point(_startPosX, _startPosY + 100),
@@ -130,7 +157,7 @@
new Point(_startPosX + 200, _startPosY + 85),
new Point(_startPosX + 170, _startPosY + 85),
};
- g.DrawPolygon(pen, BackLeftWing);
+ g.DrawPolygon(Pen, BackLeftWing);
Point[] BackRightWing = {
new Point(_startPosX + 170, _startPosY + 130),
@@ -138,39 +165,7 @@
new Point(_startPosX + 200, _startPosY + 115),
new Point(_startPosX + 170, _startPosY + 115),
};
- g.DrawPolygon(pen, BackRightWing);
-
-
- /** Отрисовка дополнительных элементов */
- if (EntityBomber.FuelTanks)
- {
- Point[] LeftGasTank = {
- new Point(_startPosX + 50, _startPosY + 85),
- new Point(_startPosX + 75, _startPosY + 85),
- new Point(_startPosX + 75, _startPosY + 70),
- new Point(_startPosX + 50, _startPosY + 70),
- };
- g.FillPolygon(AdditionalBrush, LeftGasTank);
-
- Point[] RightGasTank = {
- new Point(_startPosX + 50, _startPosY + 115),
- new Point(_startPosX + 75, _startPosY + 115),
- new Point(_startPosX + 75, _startPosY + 130),
- new Point(_startPosX + 50, _startPosY + 130),
- };
- g.FillPolygon(AdditionalBrush, RightGasTank);
- }
-
- if (EntityBomber.Bombs)
- {
- Point LeftBombStartXY = new Point(_startPosX + 110, _startPosY + 115);
- Size LeftBombSize = new Size(50, 25);
- g.FillEllipse(AdditionalBrush, new Rectangle(LeftBombStartXY, LeftBombSize));
-
- Point RightBombStartXY = new Point(_startPosX + 110, _startPosY + 60);
- Size RightBombSize = new Size(50, 25);
- g.FillEllipse(AdditionalBrush, new Rectangle(RightBombStartXY, RightBombSize));
- }
+ g.DrawPolygon(Pen, BackRightWing);
}
}
}