From 32f663fb1e973482665e04069ff1f5a43c1821bd Mon Sep 17 00:00:00 2001 From: alhimek17 Date: Sun, 10 Mar 2024 20:34:24 +0400 Subject: [PATCH 1/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=20=E2=84=961?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- ProjectAirPlane/ProjectAirPlane.sln | 2 +- .../ProjectAirPlane/DirectionType.cs | 27 + .../ProjectAirPlane/DrawningAirPlane.cs | 253 ++++++++ .../ProjectAirPlane/EntityAirPlane.cs | 69 +++ .../ProjectAirPlane/Form1.Designer.cs | 39 -- ProjectAirPlane/ProjectAirPlane/Form1.cs | 10 - .../ProjectAirPlane/FormAirPlane.Designer.cs | 135 +++++ .../ProjectAirPlane/FormAirPlane.cs | 90 +++ .../ProjectAirPlane/FormAirPlane.resx | 555 ++++++++++++++++++ ProjectAirPlane/ProjectAirPlane/Program.cs | 2 +- .../ProjectAirPlane/ProjectAirPlane.csproj | 15 + .../Properties/Resources.Designer.cs | 63 ++ .../{Form1.resx => Properties/Resources.resx} | 0 13 files changed, 1209 insertions(+), 51 deletions(-) create mode 100644 ProjectAirPlane/ProjectAirPlane/DirectionType.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs delete mode 100644 ProjectAirPlane/ProjectAirPlane/Form1.Designer.cs delete mode 100644 ProjectAirPlane/ProjectAirPlane/Form1.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx create mode 100644 ProjectAirPlane/ProjectAirPlane/Properties/Resources.Designer.cs rename ProjectAirPlane/ProjectAirPlane/{Form1.resx => Properties/Resources.resx} (100%) diff --git a/ProjectAirPlane/ProjectAirPlane.sln b/ProjectAirPlane/ProjectAirPlane.sln index ba2feb3..d8185d7 100644 --- a/ProjectAirPlane/ProjectAirPlane.sln +++ b/ProjectAirPlane/ProjectAirPlane.sln @@ -3,7 +3,7 @@ Microsoft Visual Studio Solution File, Format Version 12.00 # Visual Studio Version 17 VisualStudioVersion = 17.8.34525.116 MinimumVisualStudioVersion = 10.0.40219.1 -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ProjectAirPlane", "ProjectAirPlane\ProjectAirPlane.csproj", "{36780227-CEDB-4504-AF69-0EB987304B89}" +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "ProjectAirPlane", "ProjectAirPlane\ProjectAirPlane.csproj", "{36780227-CEDB-4504-AF69-0EB987304B89}" EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution diff --git a/ProjectAirPlane/ProjectAirPlane/DirectionType.cs b/ProjectAirPlane/ProjectAirPlane/DirectionType.cs new file mode 100644 index 0000000..6bd8f4c --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/DirectionType.cs @@ -0,0 +1,27 @@ +namespace ProjectAirPlane; + +/// +/// Направление перемещения +/// +public enum DirectionType +{ + /// + /// Вверх + /// + Up = 1, + + /// + /// Вниз + /// + Down = 2, + + /// + /// Влево + /// + Left = 3, + + /// + /// Вправо + /// + Right = 4 +} diff --git a/ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs new file mode 100644 index 0000000..39362e4 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs @@ -0,0 +1,253 @@ +namespace ProjectAirPlane; + +/// +/// Класс, отвечающий за прорисовку и перемещение объекта-сущности +/// +public class DrawningAirPlane +{ + /// + /// Класс-сущность + /// + public EntityAirPlane? EntityAirPlane { get; private set; } + + /// + /// Ширина + /// + private int? _pictureWidth; + + /// + /// Высота + /// + private int? _pictureHeight; + + /// + /// Левая координата прорисовки самолёта + /// + private int? _startPosX; + + /// + /// Верхняя кооридната прорисовки самолёта + /// + private int? _startPosY; + + /// + /// Ширина прорисовки самолёта + /// + private readonly int _drawningAirPlaneWidth = 197; + + /// + /// Высота прорисовки самолёта + /// + private readonly int _drawningAirPlaneHeight = 65; + + /// + /// Инициализация свойств + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия обвеса + /// Признак наличия доп бака + /// Признак наличия шасси + public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) + { + EntityAirPlane = new EntityAirPlane(); + EntityAirPlane.Init(speed, weight, bodyColor, additionalColor, radar, dopBak, chassi); + _pictureWidth = null; + _pictureHeight = null; + _startPosX = null; + _startPosY = null; + } + + /// + /// Установка границ поля + /// + /// Ширина поля + /// Высота поля + /// true - границы заданы, false - проверка не пройдена, нельзя разместить объект в этих размерах + public bool SetPictureSize(int width, int height) + { + // TODO проверка, что объект "влезает" в размеры поля + if (_drawningAirPlaneWidth > width || _drawningAirPlaneHeight > height) + { + return false; + } + + _pictureWidth = width; + _pictureHeight = height; + if (_startPosX.HasValue || _startPosY.HasValue) + { + if (_startPosX + _drawningAirPlaneWidth > _pictureWidth) + { + _startPosX = _pictureWidth - _drawningAirPlaneWidth; + } + else if (_startPosX < 0) _startPosX = 0; + if (_startPosY + _drawningAirPlaneHeight > _pictureHeight) + { + _startPosY = _pictureHeight - _drawningAirPlaneHeight; + } + else if (_startPosY < 0) _startPosY = 0; + } + return true; + + } + + /// + /// Установка позиции + /// + /// Координата X + /// Координата Y + public void SetPosition(int x, int y) + { + if (!_pictureHeight.HasValue || !_pictureWidth.HasValue) + { + return; + } + + // TODO если при установке объекта в эти координаты, он будет "выходить" за границы формы + + if (x + _drawningAirPlaneWidth > _pictureWidth) + { + _startPosX = _pictureWidth - _drawningAirPlaneWidth; + } + else if (x < 0) _startPosX = 0; + else _startPosX = x; + + if (x + _drawningAirPlaneHeight > _pictureHeight) + { + _startPosY = _pictureHeight - _drawningAirPlaneHeight; + } + else if (y < 0) _startPosX = 0; + _startPosY = y; + + } + + /// + /// Изменение направления перемещения + /// + /// Направление + /// true - перемещене выполнено, false - перемещение невозможно + public bool MoveTransport(DirectionType direction) + { + if (EntityAirPlane == null || !_startPosX.HasValue || !_startPosY.HasValue) + { + return false; + } + + switch (direction) + { + //влево + case DirectionType.Left: + if (_startPosX.Value - EntityAirPlane.Step > 0) + { + _startPosX -= (int)EntityAirPlane.Step; + } + return true; + //вверх + case DirectionType.Up: + if (_startPosY.Value - EntityAirPlane.Step > 0) + { + _startPosY -= (int)EntityAirPlane.Step; + } + return true; + // вправо + case DirectionType.Right: + //TODO прописать логику сдвига вправо + if (_startPosX + EntityAirPlane.Step + _drawningAirPlaneWidth < _pictureWidth) + { + _startPosX += (int)EntityAirPlane.Step; + } + return true; + //вниз + case DirectionType.Down: + //TODO прописать логику сдвига ввниз + if (_startPosY + EntityAirPlane.Step + _drawningAirPlaneHeight < _pictureHeight) + { + _startPosY += (int)EntityAirPlane.Step; + } + return true; + default: + return false; + } + } + + /// + /// Прорисовка объекта + /// + /// + public void DrawTransport(Graphics g) + { + if (EntityAirPlane == null || !_startPosX.HasValue || !_startPosY.HasValue) + { + return; + } + + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(EntityAirPlane.AdditionalColor); + + // корпус + Brush br = new SolidBrush(EntityAirPlane.BodyColor); + g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 25, 170, 30); + g.FillRectangle(br, _startPosX.Value, _startPosY.Value + 25, 170, 30); + // бак + Brush blackBrush = new SolidBrush(Color.Black); + g.FillEllipse(blackBrush, _startPosX.Value + 75, _startPosY.Value + 30, 50, 10); + // нос самолёта + Pen blackPen = new Pen(Color.Black, 2); + Brush blueBrush = new SolidBrush(Color.LightBlue); + Point point1 = new Point(_startPosX.Value + 170, _startPosY.Value + 25); + Point point2 = new Point(_startPosX.Value + 200, _startPosY.Value + 40); + Point point3 = new Point(_startPosX.Value + 170, _startPosY.Value + 55); + Point[] curvePoints = + { + point1, + point2, + point3, + }; + g.FillPolygon(blueBrush, curvePoints); + g.DrawPolygon(blackPen, curvePoints); + g.DrawLine(blackPen, _startPosX.Value + 170, _startPosY.Value + 40, _startPosX.Value + 200, _startPosY.Value + 40); + // хвост + Brush bw = new SolidBrush(EntityAirPlane.BodyColor); + g.FillPolygon(bw, new Point[] + { + new Point((int) _startPosX, (int) _startPosY + 40 ), new Point((int) _startPosX + 80, (int) _startPosY + 30), + new Point((int) _startPosX, (int) _startPosY), new Point((int) _startPosX , (int) _startPosY + 40), + + + + } + ); + // шасси + g.DrawLine(blackPen, _startPosX.Value + 50, _startPosY.Value + 55, _startPosX.Value + 50, _startPosY.Value + 70); + g.DrawLine(blackPen, _startPosX.Value + 150, _startPosY.Value + 55, _startPosX.Value + 150, _startPosY.Value + 70); + g.FillEllipse(blackBrush, _startPosX.Value + 40, _startPosY.Value + 65, 10, 10); + g.FillEllipse(blackBrush, _startPosX.Value + 50, _startPosY.Value + 65, 10, 10); + g.FillEllipse(blackBrush, _startPosX.Value + 145, _startPosY.Value + 65, 10, 10); + if (EntityAirPlane.DopBak) + { + //бак + g.FillEllipse(additionalBrush, _startPosX.Value, _startPosY.Value + 45, 40, 20); + g.DrawEllipse(blackPen, _startPosX.Value, _startPosY.Value + 45, 40, 20); + } + if (EntityAirPlane.Radar) + { + //радар + g.DrawLine(blackPen, _startPosX.Value + 60, _startPosY.Value + 25, _startPosX.Value + 60, _startPosY.Value + 15); + g.DrawLine(blackPen, _startPosX.Value + 60, _startPosY.Value + 15, _startPosX.Value + 67, _startPosY.Value + 11); + Point point7 = new Point(_startPosX.Value + 60, _startPosY.Value + 15); + Point point8 = new Point(_startPosX.Value + 60, _startPosY.Value + 5); + Point point9 = new Point(_startPosX.Value + 70, _startPosY.Value + 25); + Point[] curvePoints3 = + { + point7, + point8, + point9, + }; + g.FillPolygon(additionalBrush, curvePoints3); + + + } + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs new file mode 100644 index 0000000..5927f6c --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs @@ -0,0 +1,69 @@ +namespace ProjectAirPlane; + +/// +/// Класс-сущность "Самолёт" +/// +public class EntityAirPlane +{ + /// + /// Скорость + /// + 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 Radar { get; private set; } + + /// + /// Признак (опция) наличия доп бака + /// + public bool DopBak { get; private set; } + + /// + /// Признак (опция) наличия шасси + /// + public bool Chassi { get; private set; } + + /// + /// Шаг перемещения автомобиля + /// + public double Step => Speed * 100 / Weight; + + /// + /// Инициализация полей объекта-класса спортивного автомобиля + /// + /// Скорость + /// Вес самолёта + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия радара + /// Признак наличия доп бака + /// Признак наличия шасси + public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + AdditionalColor = additionalColor; + Radar = radar; + DopBak = dopBak; + Chassi = chassi; + + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/Form1.Designer.cs b/ProjectAirPlane/ProjectAirPlane/Form1.Designer.cs deleted file mode 100644 index be1a087..0000000 --- a/ProjectAirPlane/ProjectAirPlane/Form1.Designer.cs +++ /dev/null @@ -1,39 +0,0 @@ -namespace ProjectAirPlane -{ - partial class Form1 - { - /// - /// Required designer variable. - /// - private System.ComponentModel.IContainer components = null; - - /// - /// Clean up any resources being used. - /// - /// true if managed resources should be disposed; otherwise, false. - protected override void Dispose(bool disposing) - { - if (disposing && (components != null)) - { - components.Dispose(); - } - base.Dispose(disposing); - } - - #region Windows Form Designer generated code - - /// - /// Required method for Designer support - do not modify - /// the contents of this method with the code editor. - /// - private void InitializeComponent() - { - this.components = new System.ComponentModel.Container(); - this.AutoScaleMode = System.Windows.Forms.AutoScaleMode.Font; - this.ClientSize = new System.Drawing.Size(800, 450); - this.Text = "Form1"; - } - - #endregion - } -} diff --git a/ProjectAirPlane/ProjectAirPlane/Form1.cs b/ProjectAirPlane/ProjectAirPlane/Form1.cs deleted file mode 100644 index 7d12854..0000000 --- a/ProjectAirPlane/ProjectAirPlane/Form1.cs +++ /dev/null @@ -1,10 +0,0 @@ -namespace ProjectAirPlane -{ - public partial class Form1 : Form - { - public Form1() - { - InitializeComponent(); - } - } -} diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs new file mode 100644 index 0000000..c841c7e --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs @@ -0,0 +1,135 @@ +namespace ProjectAirPlane +{ + partial class FormAirPlane + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormAirPlane)); + pictureBoxAirPlane = new PictureBox(); + buttonCreateAirPlane = new Button(); + buttonLeft = new Button(); + buttonUp = new Button(); + buttonDown = new Button(); + buttonRight = new Button(); + ((System.ComponentModel.ISupportInitialize)pictureBoxAirPlane).BeginInit(); + SuspendLayout(); + // + // pictureBoxAirPlane + // + pictureBoxAirPlane.Dock = DockStyle.Fill; + pictureBoxAirPlane.Location = new Point(0, 0); + pictureBoxAirPlane.Name = "pictureBoxAirPlane"; + pictureBoxAirPlane.Size = new Size(749, 523); + pictureBoxAirPlane.TabIndex = 0; + pictureBoxAirPlane.TabStop = false; + // + // buttonCreateAirPlane + // + buttonCreateAirPlane.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + buttonCreateAirPlane.Location = new Point(12, 488); + buttonCreateAirPlane.Name = "buttonCreateAirPlane"; + buttonCreateAirPlane.Size = new Size(75, 23); + buttonCreateAirPlane.TabIndex = 1; + buttonCreateAirPlane.Text = "Создать"; + buttonCreateAirPlane.UseVisualStyleBackColor = true; + buttonCreateAirPlane.Click += ButtonCreateAirPlane_Click; + // + // buttonLeft + // + buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonLeft.BackgroundImage = (Image)resources.GetObject("buttonLeft.BackgroundImage"); + buttonLeft.BackgroundImageLayout = ImageLayout.Stretch; + buttonLeft.Location = new Point(613, 476); + buttonLeft.Name = "buttonLeft"; + buttonLeft.Size = new Size(35, 35); + buttonLeft.TabIndex = 2; + buttonLeft.UseVisualStyleBackColor = true; + buttonLeft.Click += ButtonMove_Click; + // + // buttonUp + // + buttonUp.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonUp.BackgroundImage = (Image)resources.GetObject("buttonUp.BackgroundImage"); + buttonUp.BackgroundImageLayout = ImageLayout.Stretch; + buttonUp.Location = new Point(654, 435); + buttonUp.Name = "buttonUp"; + buttonUp.Size = new Size(35, 35); + buttonUp.TabIndex = 3; + buttonUp.UseVisualStyleBackColor = true; + buttonUp.Click += ButtonMove_Click; + // + // buttonDown + // + buttonDown.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonDown.BackgroundImage = (Image)resources.GetObject("buttonDown.BackgroundImage"); + buttonDown.BackgroundImageLayout = ImageLayout.Stretch; + buttonDown.Location = new Point(654, 476); + buttonDown.Name = "buttonDown"; + buttonDown.Size = new Size(35, 35); + buttonDown.TabIndex = 4; + buttonDown.UseVisualStyleBackColor = true; + buttonDown.Click += ButtonMove_Click; + // + // buttonRight + // + buttonRight.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; + buttonRight.BackgroundImage = (Image)resources.GetObject("buttonRight.BackgroundImage"); + buttonRight.BackgroundImageLayout = ImageLayout.Stretch; + buttonRight.Location = new Point(695, 476); + buttonRight.Name = "buttonRight"; + buttonRight.Size = new Size(35, 35); + buttonRight.TabIndex = 5; + buttonRight.UseVisualStyleBackColor = true; + buttonRight.Click += ButtonMove_Click; + // + // FormAirPlane + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(749, 523); + Controls.Add(buttonRight); + Controls.Add(buttonDown); + Controls.Add(buttonUp); + Controls.Add(buttonLeft); + Controls.Add(buttonCreateAirPlane); + Controls.Add(pictureBoxAirPlane); + Name = "FormAirPlane"; + Text = "Спортивный автомобиль"; + ((System.ComponentModel.ISupportInitialize)pictureBoxAirPlane).EndInit(); + ResumeLayout(false); + } + + #endregion + + private PictureBox pictureBoxAirPlane; + private Button buttonCreateAirPlane; + private Button buttonLeft; + private Button buttonUp; + private Button buttonDown; + private Button buttonRight; + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs new file mode 100644 index 0000000..531826e --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs @@ -0,0 +1,90 @@ +namespace ProjectAirPlane; + +/// +/// "" +/// +public partial class FormAirPlane : Form +{ + /// + /// - + /// + private DrawningAirPlane? _drawningAirPlane; + + /// + /// + /// + public FormAirPlane() + { + InitializeComponent(); + } + + /// + /// + /// + private void Draw() + { + if (_drawningAirPlane == null) + { + return; + } + + Bitmap bmp = new(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); + Graphics gr = Graphics.FromImage(bmp); + _drawningAirPlane.DrawTransport(gr); + pictureBoxAirPlane.Image = bmp; + } + + /// + /// "" + /// + /// + /// + private void ButtonCreateAirPlane_Click(object sender, EventArgs e) + { + Random random = new(); + _drawningAirPlane = new DrawningAirPlane(); + _drawningAirPlane.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))); + _drawningAirPlane.SetPictureSize(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); + _drawningAirPlane.SetPosition(random.Next(10, 100), random.Next(10, 100)); + Draw(); + } + + /// + /// ( ) + /// + /// + /// + private void ButtonMove_Click(object sender, EventArgs e) + { + if (_drawningAirPlane == null) + { + return; + } + + string name = ((Button)sender)?.Name ?? string.Empty; + bool result = false; + switch (name) + { + case "buttonUp": + result = _drawningAirPlane.MoveTransport(DirectionType.Up); + break; + case "buttonDown": + result = _drawningAirPlane.MoveTransport(DirectionType.Down); + break; + case "buttonLeft": + result = _drawningAirPlane.MoveTransport(DirectionType.Left); + break; + case "buttonRight": + result = _drawningAirPlane.MoveTransport(DirectionType.Right); + break; + } + + if (result) + { + Draw(); + } + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx new file mode 100644 index 0000000..8014d25 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx @@ -0,0 +1,555 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + + + 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 + AAAASUVORK5CYII= + + + + + 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 + CgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAb + xRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC6 + 1SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgA + oACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACw + UQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyh + W40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40C + AAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoA + G8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQ + utUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUo + AKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAA + sFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEM + oVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuN + AgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAK + ABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvF + ELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrV + KACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACg + ALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBR + DKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFb + jQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIA + CgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAb + xRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC6 + 1SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgA + oACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACw + UQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyh + W40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40C + AAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoA + G8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQ + utUoAKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUo + AKAAsFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAA + sFEMoVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEM + oVuNAgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuN + AgAKABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAK + ABvFELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvF + ELrVKACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrV + KACgALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACg + ALBRDKFbjQIACgAbxRC61SgAoACwUQyhW40CAAoAG8UQutUoAKAAsFEMoVuNAgAKABvFELrVKACgALBR + DKFbjQIACgAbxRC61XxyWYJwVX8tvQ+4hxjCPdT84rII4Yr+XHobcA8xhHuo+YllEcIV/fH0NuAeYgj3 + UPP9yyKEK/q29DbgHmII91Dz2WURwtV8sXwsvQ24hxjCPdT8prkI4Yq+N70LuJcYwr3U/JtlIcKV/P70 + JuBeYgj3UvOZZSHCVfxAeg9wTzGEe6r5x8tihCv4HektwD3FEO6p5tPlZ+dihLP7zvQO4N5iCPdW8zvL + L80FCWf1T8tH0xuAe4sh7FDzh8v/LuvChLP4V+UT6duHHWIIu9T89uL/DuBs/mb51embh11iCDvVjL8m + 4O+XXynrEoWj+W/lj6XvHHaLITyCmt9S/kn55bIuVXh0P1P+TPna9G3DI4ghPJKary9/tIw/KzD+wUE/ + VfwFgzyKL5QfKZ8r31G+tbyTvmV4HF/6yP8FqdbUgRJva58AAAAASUVORK5CYII= + + + + + iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP + RQAAD0UBxeoB7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABrPSURBVHhe7d1f + yLZrWhbwWSM1hMM0SoEwzpL+7QdBYSlM4FbtFG1Y7bRV0FY0OyFBQUWCqZthG4JFRYVEErWTQwWRSkSS + JIKpYWmYNU0oSGM4nVdzTetaax3fn/d9n+e8nvu+fyf8dg5hRnju6zyPWbPmWx/50pe+BA+t5p3yjeU7 + yufKj5cvlPF/hN2+WH62/Ej5++VPlK9N3zI8khjCI6j56vLny8+XdeHCo/vV8k/K70rfNjyCGMJuNX+y + /NeyLlU4ml8r468KfDp957BTDGGXml9f/mZZlygc3S+U35u+edglhrBDzSfKvyrr4oSz+N/lj6VvH3aI + IXSr+Wj5p2VdmHA2428Y/Kb0BqBbDKFbzXfOBQlnN/7rAH9PANvFEDrV/L65GOEq/nF6C9AphtCp5oeW + xQhX8Zn0HqBLDKFLzR9eFiJcyY+kNwFdYghdar5/WYhwNb89vQvoEEPoUPOx8ktzEcIVfTa9DegQQ+hQ + 8y3LIoQr+sH0NqBDDKFDzZ9aFiFc0U+ntwEdYggdav7isgjhin4lvQ3oEEPoUPM9yyKEq/pkeh9wbzGE + DjXftyxBuKqvS+8D7i2G0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWA + TWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWII + HWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoU + AFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA + 2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG + 0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFG + AQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAF + gE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1i + CB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1q + FABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQ + ANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgk + htChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtCh + RgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEA + BYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBN + YggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggd + ahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQA + UADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADY + JIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQ + oUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYB + AAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWA + TWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWII + HWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoU + AFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA + 2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG + 0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFG + AQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAF + gE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1i + CB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1q + FABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQ + ANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgk + htChRgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtCh + RgEABYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEA + BYBNYggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBN + YggdahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggd + ahQAUADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQA + UADYJIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADY + JIbQoUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQ + oUYBAAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYB + AAWATWIIHWoUAFAA2CSG0KFGAQAFgE1iCB1qFABQANgkhtChRgEABYBNYggdahQAUADYJIbQoUYBAAWA + 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 + SUVORK5CYII= + + + \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/Program.cs b/ProjectAirPlane/ProjectAirPlane/Program.cs index bc2d17a..37a9525 100644 --- a/ProjectAirPlane/ProjectAirPlane/Program.cs +++ b/ProjectAirPlane/ProjectAirPlane/Program.cs @@ -11,7 +11,7 @@ namespace ProjectAirPlane // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new Form1()); + Application.Run(new FormAirPlane()); } } } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/ProjectAirPlane.csproj b/ProjectAirPlane/ProjectAirPlane/ProjectAirPlane.csproj index e1a0735..244387d 100644 --- a/ProjectAirPlane/ProjectAirPlane/ProjectAirPlane.csproj +++ b/ProjectAirPlane/ProjectAirPlane/ProjectAirPlane.csproj @@ -8,4 +8,19 @@ enable + + + True + True + Resources.resx + + + + + + ResXFileCodeGenerator + Resources.Designer.cs + + + \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/Properties/Resources.Designer.cs b/ProjectAirPlane/ProjectAirPlane/Properties/Resources.Designer.cs new file mode 100644 index 0000000..03696f3 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/Properties/Resources.Designer.cs @@ -0,0 +1,63 @@ +//------------------------------------------------------------------------------ +// +// Этот код создан программой. +// Исполняемая версия:4.0.30319.42000 +// +// Изменения в этом файле могут привести к неправильной работе и будут потеряны в случае +// повторной генерации кода. +// +//------------------------------------------------------------------------------ + +namespace ProjectAirPlane.Properties { + using System; + + + /// + /// Класс ресурса со строгой типизацией для поиска локализованных строк и т.д. + /// + // Этот класс создан автоматически классом StronglyTypedResourceBuilder + // с помощью такого средства, как ResGen или Visual Studio. + // Чтобы добавить или удалить член, измените файл .ResX и снова запустите ResGen + // с параметром /str или перестройте свой проект VS. + [global::System.CodeDom.Compiler.GeneratedCodeAttribute("System.Resources.Tools.StronglyTypedResourceBuilder", "17.0.0.0")] + [global::System.Diagnostics.DebuggerNonUserCodeAttribute()] + [global::System.Runtime.CompilerServices.CompilerGeneratedAttribute()] + internal class Resources { + + private static global::System.Resources.ResourceManager resourceMan; + + private static global::System.Globalization.CultureInfo resourceCulture; + + [global::System.Diagnostics.CodeAnalysis.SuppressMessageAttribute("Microsoft.Performance", "CA1811:AvoidUncalledPrivateCode")] + internal Resources() { + } + + /// + /// Возвращает кэшированный экземпляр ResourceManager, использованный этим классом. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Resources.ResourceManager ResourceManager { + get { + if (object.ReferenceEquals(resourceMan, null)) { + global::System.Resources.ResourceManager temp = new global::System.Resources.ResourceManager("ProjectAirPlane.Properties.Resources", typeof(Resources).Assembly); + resourceMan = temp; + } + return resourceMan; + } + } + + /// + /// Перезаписывает свойство CurrentUICulture текущего потока для всех + /// обращений к ресурсу с помощью этого класса ресурса со строгой типизацией. + /// + [global::System.ComponentModel.EditorBrowsableAttribute(global::System.ComponentModel.EditorBrowsableState.Advanced)] + internal static global::System.Globalization.CultureInfo Culture { + get { + return resourceCulture; + } + set { + resourceCulture = value; + } + } + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/Form1.resx b/ProjectAirPlane/ProjectAirPlane/Properties/Resources.resx similarity index 100% rename from ProjectAirPlane/ProjectAirPlane/Form1.resx rename to ProjectAirPlane/ProjectAirPlane/Properties/Resources.resx -- 2.25.1 From 3a23ad0810a926c250c16bc303a73a85b7b03a79 Mon Sep 17 00:00:00 2001 From: alhimek17 Date: Sun, 10 Mar 2024 23:32:08 +0400 Subject: [PATCH 2/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=20=E2=84=962?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Drawnings/DirectionType.cs | 32 +++ .../Drawnings/DrawningAirPlane.cs | 82 ++++++++ .../DrawningPlane.cs} | 189 ++++++++---------- .../ProjectAirPlane/Entites/EntityAirPlane.cs | 52 +++++ .../ProjectAirPlane/Entites/EntityPlane.cs | 43 ++++ .../ProjectAirPlane/EntityAirPlane.cs | 69 ------- .../ProjectAirPlane/FormAirPlane.Designer.cs | 43 +++- .../ProjectAirPlane/FormAirPlane.cs | 126 +++++++++--- .../ProjectAirPlane/FormAirPlane.resx | 8 +- .../MovementStrategy/AbstractStrategy.cs | 139 +++++++++++++ .../MovementStrategy/IMoveableObject.cs | 24 +++ .../MovementStrategy/MoveToBorder.cs | 31 +++ .../MovementStrategy/MoveToCenter.cs | 55 +++++ .../MovementStrategy/MoveablePlane.cs | 61 ++++++ .../MovementDirection.cs} | 5 +- .../MovementStrategy/ObjectParameters.cs | 71 +++++++ .../MovementStrategy/StrategyStatus.cs | 22 ++ .../ProjectAirPlane/Resources/arrowDown.jpg | Bin 0 -> 62022 bytes .../ProjectAirPlane/Resources/arrowLeft.jpg | Bin 0 -> 61872 bytes .../ProjectAirPlane/Resources/arrowRight.jpg | Bin 0 -> 61715 bytes .../ProjectAirPlane/Resources/arrowUp.jpg | Bin 0 -> 62105 bytes 21 files changed, 850 insertions(+), 202 deletions(-) create mode 100644 ProjectAirPlane/ProjectAirPlane/Drawnings/DirectionType.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs rename ProjectAirPlane/ProjectAirPlane/{DrawningAirPlane.cs => Drawnings/DrawningPlane.cs} (50%) create mode 100644 ProjectAirPlane/ProjectAirPlane/Entites/EntityAirPlane.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/Entites/EntityPlane.cs delete mode 100644 ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/AbstractStrategy.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToBorder.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs rename ProjectAirPlane/ProjectAirPlane/{DirectionType.cs => MovementStrategy/MovementDirection.cs} (82%) create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/ObjectParameters.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/MovementStrategy/StrategyStatus.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/Resources/arrowDown.jpg create mode 100644 ProjectAirPlane/ProjectAirPlane/Resources/arrowLeft.jpg create mode 100644 ProjectAirPlane/ProjectAirPlane/Resources/arrowRight.jpg create mode 100644 ProjectAirPlane/ProjectAirPlane/Resources/arrowUp.jpg diff --git a/ProjectAirPlane/ProjectAirPlane/Drawnings/DirectionType.cs b/ProjectAirPlane/ProjectAirPlane/Drawnings/DirectionType.cs new file mode 100644 index 0000000..ebe8ff4 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/Drawnings/DirectionType.cs @@ -0,0 +1,32 @@ +namespace ProjectAirPlane.Drawnings; + +/// +/// Направление перемещения +/// +public enum DirectionType +{ + /// + /// Неизвестное направление + /// + Unknow = -1, + + /// + /// Вверх + /// + Up = 1, + + /// + /// Вниз + /// + Down = 2, + + /// + /// Влево + /// + Left = 3, + + /// + /// Вправо + /// + Right = 4 +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs new file mode 100644 index 0000000..85ef58d --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs @@ -0,0 +1,82 @@ +using ProjectAirPlane.Entites; + +namespace ProjectAirPlane.Drawnings; + +/// +/// Класс, отвечающий за прорисовку и перемещение объекта-сущности +/// +public class DrawningAirPlane : DrawningPlane +{ + + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия обвеса + /// Признак наличия антикрыла + /// Признак наличия гоночной полосы + public DrawningAirPlane(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) : base(190, 70) + { + EntityPlane = new EntityAirPlane(speed, weight, bodyColor, additionalColor, radar, dopBak, chassi); + + + } + + + public override void DrawTransport(Graphics g) + { + if (EntityPlane == null || EntityPlane is not EntityAirPlane airPlane || !_startPosX.HasValue || !_startPosY.HasValue) + { + return; + } + Pen pen = new(Color.Black); + Brush additionalBrush = new SolidBrush(EntityPlane.BodyColor); + + if (airPlane.Chassi) + { + //шасси + g.DrawLine(pen, _startPosX.Value + 50, _startPosY.Value + 55, _startPosX.Value + 50, _startPosY.Value + 70); + g.DrawLine(pen, _startPosX.Value + 150, _startPosY.Value + 55, _startPosX.Value + 150, _startPosY.Value + 70); + g.FillEllipse(additionalBrush, _startPosX.Value + 40, _startPosY.Value + 65, 10, 10); + g.FillEllipse(additionalBrush, _startPosX.Value + 50, _startPosY.Value + 65, 10, 10); + g.FillEllipse(additionalBrush, _startPosX.Value + 145, _startPosY.Value + 65, 10, 10); + + } + + _startPosX += 0; + _startPosY += 0; + base.DrawTransport(g); + _startPosX -= 0; + _startPosY -= 0; + + if (airPlane.DopBak) + { + //бак + g.FillEllipse(additionalBrush, _startPosX.Value, _startPosY.Value + 45, 40, 20); + g.DrawEllipse(pen, _startPosX.Value, _startPosY.Value + 45, 40, 20); + } + + //радар + g.DrawLine(pen, _startPosX.Value + 60, _startPosY.Value + 25, _startPosX.Value + 60, _startPosY.Value + 15); + g.DrawLine(pen, _startPosX.Value + 60, _startPosY.Value + 15, _startPosX.Value + 67, _startPosY.Value + 11); + Point point7 = new Point(_startPosX.Value + 60, _startPosY.Value + 15); + Point point8 = new Point(_startPosX.Value + 60, _startPosY.Value + 5); + Point point9 = new Point(_startPosX.Value + 70, _startPosY.Value + 25); + Point[] curvePoints3 = + { + point7, + point8, + point9, + }; + g.FillPolygon(additionalBrush, curvePoints3); + + + + } +} + + + \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs similarity index 50% rename from ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs rename to ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs index 39362e4..1bc812b 100644 --- a/ProjectAirPlane/ProjectAirPlane/DrawningAirPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs @@ -1,65 +1,104 @@ -namespace ProjectAirPlane; +using ProjectAirPlane.Entites; -/// -/// Класс, отвечающий за прорисовку и перемещение объекта-сущности -/// -public class DrawningAirPlane +namespace ProjectAirPlane.Drawnings; + +public class DrawningPlane { /// /// Класс-сущность /// - public EntityAirPlane? EntityAirPlane { get; private set; } + public EntityPlane? EntityPlane { get; protected set; } /// - /// Ширина + /// Ширина окна /// private int? _pictureWidth; /// - /// Высота + /// Высота окна /// private int? _pictureHeight; /// - /// Левая координата прорисовки самолёта + /// Левая координата прорисовки автомобиля /// - private int? _startPosX; + protected int? _startPosX; /// - /// Верхняя кооридната прорисовки самолёта + /// Верхняя кооридната прорисовки автомобиля /// - private int? _startPosY; + protected int? _startPosY; /// /// Ширина прорисовки самолёта /// - private readonly int _drawningAirPlaneWidth = 197; + private readonly int _drawningAirPlaneWidth = 190; /// /// Высота прорисовки самолёта /// - private readonly int _drawningAirPlaneHeight = 65; + private readonly int _drawningAirPlaneHeight = 70; /// - /// Инициализация свойств + /// Координата X объекта + /// + public int? GetPosX => _startPosX; + + /// + /// Координата Y объекта /// - /// Скорость - /// Вес - /// Основной цвет - /// Дополнительный цвет - /// Признак наличия обвеса - /// Признак наличия доп бака - /// Признак наличия шасси - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) + public int? GetPosY => _startPosY; + + /// + /// Ширина объекта + /// + public int GetWidth => _drawningAirPlaneWidth; + + /// + /// Высота объекта + /// + public int GetHeight => _drawningAirPlaneHeight; + + /// + /// Пустой конструктор + /// + private DrawningPlane() { - EntityAirPlane = new EntityAirPlane(); - EntityAirPlane.Init(speed, weight, bodyColor, additionalColor, radar, dopBak, chassi); _pictureWidth = null; _pictureHeight = null; _startPosX = null; _startPosY = null; } + /// + /// Конструктор + /// + /// Скорость + /// Вес + /// Основной цвет + + public DrawningPlane(int speed, double weight, Color bodyColor) : this() + { + + EntityPlane = new EntityPlane(speed, weight, bodyColor); + + } + + /// + /// Конструктор для наследования + /// + /// Ширина прорисовки самолёта + /// Высота прорисовки самолёта + + + protected DrawningPlane(int drawningAirPlaneWidth, int drawningAirPlaneHeight) : this() + { + _drawningAirPlaneWidth = drawningAirPlaneWidth; + _drawningAirPlaneHeight = drawningAirPlaneHeight; + + } + + /// /// Установка границ поля /// @@ -69,28 +108,11 @@ public class DrawningAirPlane public bool SetPictureSize(int width, int height) { // TODO проверка, что объект "влезает" в размеры поля - if (_drawningAirPlaneWidth > width || _drawningAirPlaneHeight > height) - { - return false; - } + // если влезает, сохраняем границы и корректируем позицию объекта, если она была уже установлена _pictureWidth = width; _pictureHeight = height; - if (_startPosX.HasValue || _startPosY.HasValue) - { - if (_startPosX + _drawningAirPlaneWidth > _pictureWidth) - { - _startPosX = _pictureWidth - _drawningAirPlaneWidth; - } - else if (_startPosX < 0) _startPosX = 0; - if (_startPosY + _drawningAirPlaneHeight > _pictureHeight) - { - _startPosY = _pictureHeight - _drawningAirPlaneHeight; - } - else if (_startPosY < 0) _startPosY = 0; - } return true; - } /// @@ -107,20 +129,15 @@ public class DrawningAirPlane // TODO если при установке объекта в эти координаты, он будет "выходить" за границы формы - if (x + _drawningAirPlaneWidth > _pictureWidth) + if (x + _drawningAirPlaneWidth >= _pictureWidth || y + _drawningAirPlaneHeight >= _pictureHeight) { - _startPosX = _pictureWidth - _drawningAirPlaneWidth; + x = y = 10; + _startPosX = x; + _startPosY = y; } - else if (x < 0) _startPosX = 0; - else _startPosX = x; - - if (x + _drawningAirPlaneHeight > _pictureHeight) - { - _startPosY = _pictureHeight - _drawningAirPlaneHeight; - } - else if (y < 0) _startPosX = 0; + // то надо изменить координаты, чтобы он оставался в этих границах + _startPosX = x; _startPosY = y; - } /// @@ -130,7 +147,7 @@ public class DrawningAirPlane /// true - перемещене выполнено, false - перемещение невозможно public bool MoveTransport(DirectionType direction) { - if (EntityAirPlane == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityPlane == null || !_startPosX.HasValue || !_startPosY.HasValue) { return false; } @@ -139,32 +156,32 @@ public class DrawningAirPlane { //влево case DirectionType.Left: - if (_startPosX.Value - EntityAirPlane.Step > 0) + if (_startPosX.Value - EntityPlane.Step > 0) { - _startPosX -= (int)EntityAirPlane.Step; + _startPosX -= (int)EntityPlane.Step; } return true; //вверх case DirectionType.Up: - if (_startPosY.Value - EntityAirPlane.Step > 0) + if (_startPosY.Value - EntityPlane.Step > 0) { - _startPosY -= (int)EntityAirPlane.Step; + _startPosY -= (int)EntityPlane.Step; } return true; // вправо case DirectionType.Right: //TODO прописать логику сдвига вправо - if (_startPosX + EntityAirPlane.Step + _drawningAirPlaneWidth < _pictureWidth) + if (_startPosX + EntityPlane.Step + _drawningAirPlaneWidth < _pictureWidth) { - _startPosX += (int)EntityAirPlane.Step; + _startPosX += (int)EntityPlane.Step; } return true; //вниз case DirectionType.Down: //TODO прописать логику сдвига ввниз - if (_startPosY + EntityAirPlane.Step + _drawningAirPlaneHeight < _pictureHeight) + if (_startPosY + EntityPlane.Step + _drawningAirPlaneHeight < _pictureHeight) { - _startPosY += (int)EntityAirPlane.Step; + _startPosY += (int)EntityPlane.Step; } return true; default: @@ -176,18 +193,18 @@ public class DrawningAirPlane /// Прорисовка объекта /// /// - public void DrawTransport(Graphics g) + public virtual void DrawTransport(Graphics g) { - if (EntityAirPlane == null || !_startPosX.HasValue || !_startPosY.HasValue) + if (EntityPlane == null || !_startPosX.HasValue || !_startPosY.HasValue) { return; } Pen pen = new(Color.Black); - Brush additionalBrush = new SolidBrush(EntityAirPlane.AdditionalColor); + Brush additionalBrush = new SolidBrush(EntityPlane.BodyColor); // корпус - Brush br = new SolidBrush(EntityAirPlane.BodyColor); + Brush br = new SolidBrush(EntityPlane.BodyColor); g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 25, 170, 30); g.FillRectangle(br, _startPosX.Value, _startPosY.Value + 25, 170, 30); // бак @@ -209,45 +226,13 @@ public class DrawningAirPlane g.DrawPolygon(blackPen, curvePoints); g.DrawLine(blackPen, _startPosX.Value + 170, _startPosY.Value + 40, _startPosX.Value + 200, _startPosY.Value + 40); // хвост - Brush bw = new SolidBrush(EntityAirPlane.BodyColor); + Brush bw = new SolidBrush(EntityPlane.BodyColor); g.FillPolygon(bw, new Point[] { new Point((int) _startPosX, (int) _startPosY + 40 ), new Point((int) _startPosX + 80, (int) _startPosY + 30), new Point((int) _startPosX, (int) _startPosY), new Point((int) _startPosX , (int) _startPosY + 40), - - - } ); - // шасси - g.DrawLine(blackPen, _startPosX.Value + 50, _startPosY.Value + 55, _startPosX.Value + 50, _startPosY.Value + 70); - g.DrawLine(blackPen, _startPosX.Value + 150, _startPosY.Value + 55, _startPosX.Value + 150, _startPosY.Value + 70); - g.FillEllipse(blackBrush, _startPosX.Value + 40, _startPosY.Value + 65, 10, 10); - g.FillEllipse(blackBrush, _startPosX.Value + 50, _startPosY.Value + 65, 10, 10); - g.FillEllipse(blackBrush, _startPosX.Value + 145, _startPosY.Value + 65, 10, 10); - if (EntityAirPlane.DopBak) - { - //бак - g.FillEllipse(additionalBrush, _startPosX.Value, _startPosY.Value + 45, 40, 20); - g.DrawEllipse(blackPen, _startPosX.Value, _startPosY.Value + 45, 40, 20); - } - if (EntityAirPlane.Radar) - { - //радар - g.DrawLine(blackPen, _startPosX.Value + 60, _startPosY.Value + 25, _startPosX.Value + 60, _startPosY.Value + 15); - g.DrawLine(blackPen, _startPosX.Value + 60, _startPosY.Value + 15, _startPosX.Value + 67, _startPosY.Value + 11); - Point point7 = new Point(_startPosX.Value + 60, _startPosY.Value + 15); - Point point8 = new Point(_startPosX.Value + 60, _startPosY.Value + 5); - Point point9 = new Point(_startPosX.Value + 70, _startPosY.Value + 25); - Point[] curvePoints3 = - { - point7, - point8, - point9, - }; - g.FillPolygon(additionalBrush, curvePoints3); - - - } } -} \ No newline at end of file +} + diff --git a/ProjectAirPlane/ProjectAirPlane/Entites/EntityAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/Entites/EntityAirPlane.cs new file mode 100644 index 0000000..c560690 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/Entites/EntityAirPlane.cs @@ -0,0 +1,52 @@ +namespace ProjectAirPlane.Entites; + +/// +/// Класс-сущность "Спортивный самолёт" +/// +public class EntityAirPlane : EntityPlane +{ + /// + /// Дополнительный цвет (для опциональных элементов) + /// + public Color AdditionalColor { get; private set; } + + /// + /// Признак (опция) наличия обвеса + /// + public bool Radar { get; private set; } + + /// + /// Признак (опция) наличия антикрыла + /// + public bool DopBak { get; private set; } + + /// + /// Признак (опция) наличия гоночной полосы + /// + public bool Chassi { get; private set; } + + /// + /// Шаг перемещения автомобиля + /// + + + /// + /// Инициализация полей объекта-класса спортивного автомобиля + /// + /// Скорость + /// Вес автомобиля + /// Основной цвет + /// Дополнительный цвет + /// Признак наличия обвеса + /// Признак наличия антикрыла + /// Признак наличия гоночной полосы + public EntityAirPlane(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) : base(speed, weight, bodyColor) + { + + AdditionalColor = additionalColor; + Radar = radar; + DopBak = dopBak; + Chassi = chassi; + + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/Entites/EntityPlane.cs b/ProjectAirPlane/ProjectAirPlane/Entites/EntityPlane.cs new file mode 100644 index 0000000..5b0f796 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/Entites/EntityPlane.cs @@ -0,0 +1,43 @@ +namespace ProjectAirPlane.Entites; + +/// +/// Класс-сущность "Обычный самолёт" +/// +public class EntityPlane +{ + /// + /// Скорость + /// + public int Speed { get; private set; } + + /// + /// Вес + /// + public double Weight { get; private set; } + + /// + /// Основной цвет + /// + public Color BodyColor { get; private set; } + + /// + /// Шаг перемещения автомобиля + /// + public double Step => Speed * 100 / Weight; + + /// + /// Конструктор сущности + /// + /// Скорость + /// Вес автомобиля + /// Основной цвет + + public EntityPlane(int speed, double weight, Color bodyColor) + { + Speed = speed; + Weight = weight; + BodyColor = bodyColor; + + + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs deleted file mode 100644 index 5927f6c..0000000 --- a/ProjectAirPlane/ProjectAirPlane/EntityAirPlane.cs +++ /dev/null @@ -1,69 +0,0 @@ -namespace ProjectAirPlane; - -/// -/// Класс-сущность "Самолёт" -/// -public class EntityAirPlane -{ - /// - /// Скорость - /// - 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 Radar { get; private set; } - - /// - /// Признак (опция) наличия доп бака - /// - public bool DopBak { get; private set; } - - /// - /// Признак (опция) наличия шасси - /// - public bool Chassi { get; private set; } - - /// - /// Шаг перемещения автомобиля - /// - public double Step => Speed * 100 / Weight; - - /// - /// Инициализация полей объекта-класса спортивного автомобиля - /// - /// Скорость - /// Вес самолёта - /// Основной цвет - /// Дополнительный цвет - /// Признак наличия радара - /// Признак наличия доп бака - /// Признак наличия шасси - public void Init(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) - { - Speed = speed; - Weight = weight; - BodyColor = bodyColor; - AdditionalColor = additionalColor; - Radar = radar; - DopBak = dopBak; - Chassi = chassi; - - } -} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs index c841c7e..6a010fa 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs @@ -35,6 +35,9 @@ buttonUp = new Button(); buttonDown = new Button(); buttonRight = new Button(); + ButtonCreatePlane = new Button(); + comboBoxStrategy = new ComboBox(); + buttonStrategyStepS = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxAirPlane).BeginInit(); SuspendLayout(); // @@ -52,9 +55,9 @@ buttonCreateAirPlane.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; buttonCreateAirPlane.Location = new Point(12, 488); buttonCreateAirPlane.Name = "buttonCreateAirPlane"; - buttonCreateAirPlane.Size = new Size(75, 23); + buttonCreateAirPlane.Size = new Size(180, 23); buttonCreateAirPlane.TabIndex = 1; - buttonCreateAirPlane.Text = "Создать"; + buttonCreateAirPlane.Text = "Создать самолёт с радаром"; buttonCreateAirPlane.UseVisualStyleBackColor = true; buttonCreateAirPlane.Click += ButtonCreateAirPlane_Click; // @@ -106,11 +109,44 @@ buttonRight.UseVisualStyleBackColor = true; buttonRight.Click += ButtonMove_Click; // + // ButtonCreatePlane + // + ButtonCreatePlane.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; + ButtonCreatePlane.Location = new Point(198, 488); + ButtonCreatePlane.Name = "ButtonCreatePlane"; + ButtonCreatePlane.Size = new Size(180, 23); + ButtonCreatePlane.TabIndex = 6; + ButtonCreatePlane.Text = "Создать самолёт"; + ButtonCreatePlane.UseVisualStyleBackColor = true; + // + // comboBoxStrategy + // + comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxStrategy.FormattingEnabled = true; + comboBoxStrategy.Items.AddRange(new object[] { "К центру", "К краю" }); + comboBoxStrategy.Location = new Point(628, 12); + comboBoxStrategy.Name = "comboBoxStrategy"; + comboBoxStrategy.Size = new Size(121, 23); + comboBoxStrategy.TabIndex = 7; + // + // buttonStrategyStepS + // + buttonStrategyStepS.Location = new Point(654, 41); + buttonStrategyStepS.Name = "buttonStrategyStepS"; + buttonStrategyStepS.Size = new Size(75, 23); + buttonStrategyStepS.TabIndex = 8; + buttonStrategyStepS.Text = "Шаг"; + buttonStrategyStepS.UseVisualStyleBackColor = true; + buttonStrategyStepS.Click += buttonStrategyStepS_Click; + // // FormAirPlane // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; ClientSize = new Size(749, 523); + Controls.Add(buttonStrategyStepS); + Controls.Add(comboBoxStrategy); + Controls.Add(ButtonCreatePlane); Controls.Add(buttonRight); Controls.Add(buttonDown); Controls.Add(buttonUp); @@ -131,5 +167,8 @@ private Button buttonUp; private Button buttonDown; private Button buttonRight; + private Button ButtonCreatePlane; + private ComboBox comboBoxStrategy; + private Button buttonStrategyStepS; } } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs index 531826e..9620e4b 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs @@ -1,14 +1,22 @@ +using ProjectAirPlane.Drawnings; +using ProjectAirPlane.MovementStrategy; + namespace ProjectAirPlane; /// -/// "" +/// " " /// public partial class FormAirPlane : Form { /// /// - /// - private DrawningAirPlane? _drawningAirPlane; + private DrawningPlane? _drawningPlane; + + /// + /// + /// + private AbstractStrategy? _strategy; /// /// @@ -16,41 +24,70 @@ public partial class FormAirPlane : Form public FormAirPlane() { InitializeComponent(); + _strategy = null; } /// - /// + /// /// private void Draw() { - if (_drawningAirPlane == null) + if (_drawningPlane == null) { return; } Bitmap bmp = new(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); Graphics gr = Graphics.FromImage(bmp); - _drawningAirPlane.DrawTransport(gr); + _drawningPlane.DrawTransport(gr); pictureBoxAirPlane.Image = bmp; } /// - /// "" + /// - + /// + /// + private void CreateObject(string type) + { + Random random = new(); + switch (type) + { + case nameof(DrawningPlane): + _drawningPlane = new DrawningPlane(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(DrawningAirPlane): + _drawningPlane = new DrawningAirPlane(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; + } + + _drawningPlane.SetPictureSize(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); + _drawningPlane.SetPosition(random.Next(10, 100), random.Next(10, 100)); + _strategy = null; + comboBoxStrategy.Enabled = true; + Draw(); + } + + /// + /// " " /// /// /// - private void ButtonCreateAirPlane_Click(object sender, EventArgs e) - { - Random random = new(); - _drawningAirPlane = new DrawningAirPlane(); - _drawningAirPlane.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))); - _drawningAirPlane.SetPictureSize(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); - _drawningAirPlane.SetPosition(random.Next(10, 100), random.Next(10, 100)); - Draw(); - } + private void ButtonCreateAirPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningAirPlane)); + + /// + /// " " + /// + /// + /// + private void ButtonCreatePlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningPlane)); + + /// /// ( ) @@ -59,7 +96,7 @@ public partial class FormAirPlane : Form /// private void ButtonMove_Click(object sender, EventArgs e) { - if (_drawningAirPlane == null) + if (_drawningPlane == null) { return; } @@ -69,16 +106,16 @@ public partial class FormAirPlane : Form switch (name) { case "buttonUp": - result = _drawningAirPlane.MoveTransport(DirectionType.Up); + result = _drawningPlane.MoveTransport(DirectionType.Up); break; case "buttonDown": - result = _drawningAirPlane.MoveTransport(DirectionType.Down); + result = _drawningPlane.MoveTransport(DirectionType.Down); break; case "buttonLeft": - result = _drawningAirPlane.MoveTransport(DirectionType.Left); + result = _drawningPlane.MoveTransport(DirectionType.Left); break; case "buttonRight": - result = _drawningAirPlane.MoveTransport(DirectionType.Right); + result = _drawningPlane.MoveTransport(DirectionType.Right); break; } @@ -87,4 +124,47 @@ public partial class FormAirPlane : Form Draw(); } } + + /// + /// "" + /// + /// + /// + private void buttonStrategyStepS_Click(object sender, EventArgs e) + { + if (_drawningPlane == null) + { + return; + } + + if (comboBoxStrategy.Enabled) + { + _strategy = comboBoxStrategy.SelectedIndex switch + { + 0 => new MoveToCenter(), + 1 => new MoveToBorder(), + _ => null, + }; + if (_strategy == null) + { + return; + } + _strategy.SetData(new MoveablePlane(_drawningPlane), pictureBoxAirPlane.Height, pictureBoxAirPlane.Width); + } + + if (_strategy == null) + { + return; + } + + comboBoxStrategy.Enabled = false; + _strategy.MakeStep(); + Draw(); + + if (_strategy.GetStatus() == StrategyStatus.Finish) + { + comboBoxStrategy.Enabled = true; + _strategy = null; + } + } } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx index 8014d25..f8be0c1 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.resx @@ -121,7 +121,7 @@ iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP - RQAAD0UBxeoB7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABSgSURBVHhe7d1N + RAAAD0QBF63jCwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABSgSURBVHhe7d1N yK95XQbwMxM1hINpJAjqSJb7IDB6A4NWtSlaWG1aFbSKZhMSFFQUmLqMWggVJRkSSdSmpIJIJSJJEsFX TI20RkNBGsPp+s95mf955jrnPC////2779/9ueCzON9n5jz3OXMP13Vm5jxz67nnngMAdqYeAYC51SMA MLd6BADmVo8AwNzqEQCYWz0CAHOrRwBgbvUIAMytHgGAudUjADC3egQA5laPAMDc6hEAmFs9AgBzq0cA @@ -216,7 +216,7 @@ iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP - RQAAD0UBxeoB7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABrcSURBVHhe7d1N + RAAAD0QBF63jCwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABrcSURBVHhe7d1N 6LbbdRbwnBQN0hDTUqGQ5hQ/OhcEpX5AhI50ojjwY+JIwZGYiRRBQUWhth2KDgoqKipFLKITG1QQWxGx WCyF2laqrdTaGEmh2Erj2p4ds3PO9Z73//GsZz/3ff8W/CbXICfw3HutKyfn4yNf+tKXgJOr+Zryu8pf KZ8rP1K+UH6h/Gj5Z+W7y2fK16T/DOBcYgicQ80nyl8oP1dG8BQ/X0ZR+Lr0nwmcQwyBY6t5p/zJ8j/K @@ -337,7 +337,7 @@ iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP - RQAAD0UBxeoB7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABrPSURBVHhe7d1f + RAAAD0QBF63jCwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABrPSURBVHhe7d1f yLZrWhbwWSM1hMM0SoEwzpL+7QdBYSlM4FbtFG1Y7bRV0FY0OyFBQUWCqZthG4JFRYVEErWTQwWRSkSS JIKpYWmYNU0oSGM4nVdzTetaax3fn/d9n+e8nvu+fyf8dg5hRnju6zyPWbPmWx/50pe+BA+t5p3yjeU7 yufKj5cvlPF/hN2+WH62/Ej5++VPlK9N3zI8khjCI6j56vLny8+XdeHCo/vV8k/K70rfNjyCGMJuNX+y @@ -458,7 +458,7 @@ iVBORw0KGgoAAAANSUhEUgAAAgAAAAIACAYAAAD0eNT6AAAABGdBTUEAALGPC/xhBQAAAAlwSFlzAAAP - RQAAD0UBxeoB7wAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABUVSURBVHhe7d1d + RAAAD0QBF63jCwAAABl0RVh0U29mdHdhcmUAd3d3Lmlua3NjYXBlLm9yZ5vuPBoAABUVSURBVHhe7d1d yK15WQbwNRM1hMM0SoKgjvTheRAYfYFBR3VSdGB10lFBR9GchAQFFQXjx2HUgVBRUiGRRJ3UUEGkEZEU ieAnpkZa44SCpOF03+6le+3/vvfe78d67vU8/+d3wW+Yud72u9Z69rjva8rZHV566SUAYGfKEgCYW1kC AHMrSwBgbmUJAMytLAGAuZUlADC3sgQA5laWAMDcyhIAmFtZAgBzK0sAYG5lCQDMrSwBgLmVJQAwt7IE diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/AbstractStrategy.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/AbstractStrategy.cs new file mode 100644 index 0000000..a81c6fe --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/AbstractStrategy.cs @@ -0,0 +1,139 @@ +namespace ProjectAirPlane.MovementStrategy; + +/// +/// Класс-стратегия перемещения объекта +/// +public abstract class AbstractStrategy +{ + /// + /// Перемещаемый объект + /// + private IMoveableObject? _moveableObject; + + /// + /// Статус перемещения + /// + private StrategyStatus _state = StrategyStatus.NotInit; + + /// + /// Ширина поля + /// + protected int FieldWidth { get; private set; } + + /// + /// Высота поля + /// + protected int FieldHeight { get; private set; } + + /// + /// Статус перемещения + /// + public StrategyStatus GetStatus() { return _state; } + + /// + /// Установка данных + /// + /// Перемещаемый объект + /// Ширина поля + /// Высота поля + 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; + } + + /// + /// Шаг перемещения + /// + public void MakeStep() + { + if (_state != StrategyStatus.InProgress) + { + return; + } + + if (IsTargetDestinaion()) + { + _state = StrategyStatus.Finish; + return; + } + + MoveToTarget(); + } + + /// + /// Перемещение влево + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveLeft() => MoveTo(MovementDirection.Left); + + /// + /// Перемещение вправо + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveRight() => MoveTo(MovementDirection.Right); + + /// + /// Перемещение вверх + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveUp() => MoveTo(MovementDirection.Up); + + /// + /// Перемещение вниз + /// + /// Результат перемещения (true - удалось переместиться, false - неудача) + protected bool MoveDown() => MoveTo(MovementDirection.Down); + + /// + /// Параметры объекта + /// + protected ObjectParameters? GetObjectParameters => _moveableObject?.GetObjectPosition; + + /// + /// Шаг объекта + /// + /// + protected int? GetStep() + { + if (_state != StrategyStatus.InProgress) + { + return null; + } + return _moveableObject?.GetStep; + } + + /// + /// Перемещение к цели + /// + protected abstract void MoveToTarget(); + + /// + /// Достигнута ли цель + /// + /// + protected abstract bool IsTargetDestinaion(); + + /// + /// Попытка перемещения в требуемом направлении + /// + /// Направление + /// Результат попытки (true - удалось переместиться, false - неудача) + private bool MoveTo(MovementDirection movementDirection) + { + if (_state != StrategyStatus.InProgress) + { + return false; + } + + return _moveableObject?.TryMoveObject(movementDirection) ?? false; + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs new file mode 100644 index 0000000..3619424 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs @@ -0,0 +1,24 @@ +namespace ProjectAirPlane.MovementStrategy; + +/// +/// Интерфейс для работы с перемещаемым объектом +/// +public interface IMoveableObject +{ + /// + /// Получение координаты объекта + /// + ObjectParameters? GetObjectPosition { get; } + + /// + /// Шаг объекта + /// + int GetStep { get; } + + /// + /// Попытка переместить объект в указанном направлении + /// + /// Направление + /// true - объект перемещен, false - перемещение невозможно + bool TryMoveObject(MovementDirection direction); +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToBorder.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToBorder.cs new file mode 100644 index 0000000..039e6ed --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToBorder.cs @@ -0,0 +1,31 @@ +namespace ProjectAirPlane.MovementStrategy; + +public class MoveToBorder : AbstractStrategy +{ + protected override bool IsTargetDestinaion() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) return false; + + return objParams.RightBorder + GetStep() >= FieldWidth + && objParams.DownBorder + GetStep() >= FieldHeight; + } + + protected override void MoveToTarget() + { + ObjectParameters? objParams = GetObjectParameters; + if (objParams == null) return; + + int diffX = objParams.LeftBorder - FieldWidth; + if (Math.Abs(diffX) > GetStep()) + { + MoveRight(); + } + + int diffY = objParams.DownBorder - FieldHeight; + if (Math.Abs(diffY) > GetStep()) + { + MoveDown(); + } + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs new file mode 100644 index 0000000..14c1e41 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs @@ -0,0 +1,55 @@ +namespace ProjectAirPlane.MovementStrategy; + + +/// +/// Стратегия перемещения объекта в центр экрана +/// +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(); + } + } + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs new file mode 100644 index 0000000..4bc85a1 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs @@ -0,0 +1,61 @@ +using ProjectAirPlane.Drawnings; + +namespace ProjectAirPlane.MovementStrategy; + +public class MoveablePlane : IMoveableObject +{ + /// + /// Поле-объект класса DrawningPlane или его наследника + /// + private readonly DrawningPlane? _plane = null; + + /// + /// Конструктор + /// + /// Объект класса DrawningPlane + public MoveablePlane(DrawningPlane plane) + { + _plane = plane; + } + + public ObjectParameters? GetObjectPosition + { + get + { + if (_plane == null || _plane.EntityPlane == null || !_plane.GetPosX.HasValue || !_plane.GetPosY.HasValue) + { + return null; + } + return new ObjectParameters(_plane.GetPosX.Value, _plane.GetPosY.Value, _plane.GetWidth, _plane.GetHeight); + } + } + + public int GetStep => (int)(_plane?.EntityPlane?.Step ?? 0); + + public bool TryMoveObject(MovementDirection direction) + { + if (_plane == null || _plane.EntityPlane == null) + { + return false; + } + + return _plane.MoveTransport(GetDirectionType(direction)); + } + + /// + /// Конвертация из MovementDirection в DirectionType + /// + /// MovementDirection + /// DirectionType + 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, + }; + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/DirectionType.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MovementDirection.cs similarity index 82% rename from ProjectAirPlane/ProjectAirPlane/DirectionType.cs rename to ProjectAirPlane/ProjectAirPlane/MovementStrategy/MovementDirection.cs index 6bd8f4c..df16368 100644 --- a/ProjectAirPlane/ProjectAirPlane/DirectionType.cs +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MovementDirection.cs @@ -1,10 +1,11 @@ -namespace ProjectAirPlane; +namespace ProjectAirPlane.MovementStrategy; /// /// Направление перемещения /// -public enum DirectionType +public enum MovementDirection { + /// /// Вверх /// diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/ObjectParameters.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/ObjectParameters.cs new file mode 100644 index 0000000..2f4872b --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/ObjectParameters.cs @@ -0,0 +1,71 @@ +namespace ProjectAirPlane.MovementStrategy; +/// +/// Параметры-координаты объекта +/// +public class ObjectParameters +{ + /// + /// Координата X + /// + private readonly int _x; + + /// + /// Координата Y + /// + 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/ProjectAirPlane/ProjectAirPlane/MovementStrategy/StrategyStatus.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/StrategyStatus.cs new file mode 100644 index 0000000..ae076a8 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/StrategyStatus.cs @@ -0,0 +1,22 @@ +namespace ProjectAirPlane.MovementStrategy; + +/// +/// Статус выполнения операции перемещения +/// +public enum StrategyStatus +{ + /// + /// Все готово к началу + /// + NotInit, + + /// + /// Выполняется + /// + InProgress, + + /// + /// Завершено + /// + Finish +} diff --git a/ProjectAirPlane/ProjectAirPlane/Resources/arrowDown.jpg b/ProjectAirPlane/ProjectAirPlane/Resources/arrowDown.jpg new file mode 100644 index 0000000000000000000000000000000000000000..f21002e9dce74a1a585cf193d689dabca519cdff GIT binary patch literal 62022 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 av7M8J~td~%> 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 OjHZEMlm?jp-vj_Aq!j}I literal 0 HcmV?d00001 diff --git a/ProjectAirPlane/ProjectAirPlane/Resources/arrowRight.jpg b/ProjectAirPlane/ProjectAirPlane/Resources/arrowRight.jpg new file mode 100644 index 0000000000000000000000000000000000000000..b440197337637a3901527809017ac3875c61ab4d GIT binary patch literal 61715 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 literal 0 HcmV?d00001 diff --git a/ProjectAirPlane/ProjectAirPlane/Resources/arrowUp.jpg b/ProjectAirPlane/ProjectAirPlane/Resources/arrowUp.jpg new file mode 100644 index 0000000000000000000000000000000000000000..e630cea81778990ee584c30bf17b379509fe52d8 GIT binary patch literal 62105 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 a8 Date: Tue, 12 Mar 2024 19:15:04 +0400 Subject: [PATCH 3/7] =?UTF-8?q?=D0=94=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0=D0=BD?= =?UTF-8?q?=D0=BD=D0=B0=D1=8F=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=E2=84=962?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../Drawnings/DrawningAirPlane.cs | 19 +++++----- .../Drawnings/DrawningPlane.cs | 36 +++++++++++++++---- .../ProjectAirPlane/FormAirPlane.Designer.cs | 3 +- .../ProjectAirPlane/FormAirPlane.cs | 12 +++---- .../MovementStrategy/IMoveableObject.cs | 2 ++ .../MovementStrategy/MoveToCenter.cs | 11 +++--- .../MovementStrategy/MoveablePlane.cs | 5 +++ 7 files changed, 59 insertions(+), 29 deletions(-) diff --git a/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs index 85ef58d..5b24d56 100644 --- a/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningAirPlane.cs @@ -18,7 +18,7 @@ public class DrawningAirPlane : DrawningPlane /// Признак наличия обвеса /// Признак наличия антикрыла /// Признак наличия гоночной полосы - public DrawningAirPlane(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) : base(190, 70) + public DrawningAirPlane(int speed, double weight, Color bodyColor, Color additionalColor, bool radar, bool dopBak, bool chassi) : base(195, 70) { EntityPlane = new EntityAirPlane(speed, weight, bodyColor, additionalColor, radar, dopBak, chassi); @@ -46,19 +46,21 @@ public class DrawningAirPlane : DrawningPlane } - _startPosX += 0; - _startPosY += 0; + base.DrawTransport(g); - _startPosX -= 0; - _startPosY -= 0; + + if (airPlane.DopBak) { //бак g.FillEllipse(additionalBrush, _startPosX.Value, _startPosY.Value + 45, 40, 20); g.DrawEllipse(pen, _startPosX.Value, _startPosY.Value + 45, 40, 20); + } - + + if (airPlane.Radar) + { //радар g.DrawLine(pen, _startPosX.Value + 60, _startPosY.Value + 25, _startPosX.Value + 60, _startPosY.Value + 15); g.DrawLine(pen, _startPosX.Value + 60, _startPosY.Value + 15, _startPosX.Value + 67, _startPosY.Value + 11); @@ -73,10 +75,9 @@ public class DrawningAirPlane : DrawningPlane }; g.FillPolygon(additionalBrush, curvePoints3); + } - } } - - \ No newline at end of file + diff --git a/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs index 1bc812b..ffcadd5 100644 --- a/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/Drawnings/DrawningPlane.cs @@ -32,7 +32,7 @@ public class DrawningPlane /// /// Ширина прорисовки самолёта /// - private readonly int _drawningAirPlaneWidth = 190; + private readonly int _drawningAirPlaneWidth = 195; /// /// Высота прорисовки самолёта @@ -79,7 +79,7 @@ public class DrawningPlane public DrawningPlane(int speed, double weight, Color bodyColor) : this() { - + EntityPlane = new EntityPlane(speed, weight, bodyColor); } @@ -91,10 +91,10 @@ public class DrawningPlane /// Высота прорисовки самолёта - protected DrawningPlane(int drawningAirPlaneWidth, int drawningAirPlaneHeight) : this() + protected DrawningPlane(int drawningPlaneWidth, int drawningPlaneHeight) : this() { - _drawningAirPlaneWidth = drawningAirPlaneWidth; - _drawningAirPlaneHeight = drawningAirPlaneHeight; + _drawningAirPlaneWidth = drawningPlaneWidth; + _drawningAirPlaneHeight = drawningPlaneHeight; } @@ -109,9 +109,26 @@ public class DrawningPlane { // TODO проверка, что объект "влезает" в размеры поля - // если влезает, сохраняем границы и корректируем позицию объекта, если она была уже установлена + if (_drawningAirPlaneWidth > width || _drawningAirPlaneHeight > height) + { + return false; + } + _pictureWidth = width; _pictureHeight = height; + if (_startPosX.HasValue || _startPosY.HasValue) + { + if (_startPosX + _drawningAirPlaneWidth > _pictureWidth) + { + _startPosX = _pictureWidth - _drawningAirPlaneWidth; + } + else if (_startPosX < 0) _startPosX = 0; + if (_startPosY + _drawningAirPlaneHeight > _pictureHeight) + { + _startPosY = _pictureHeight - _drawningAirPlaneHeight; + } + else if (_startPosY < 0) _startPosY = 0; + } return true; } @@ -203,6 +220,13 @@ public class DrawningPlane Pen pen = new(Color.Black); Brush additionalBrush = new SolidBrush(EntityPlane.BodyColor); + + //шасси + g.DrawLine(pen, _startPosX.Value + 50, _startPosY.Value + 55, _startPosX.Value + 50, _startPosY.Value + 70); + g.DrawLine(pen, _startPosX.Value + 150, _startPosY.Value + 55, _startPosX.Value + 150, _startPosY.Value + 70); + g.FillEllipse(additionalBrush, _startPosX.Value + 40, _startPosY.Value + 65, 10, 10); + g.FillEllipse(additionalBrush, _startPosX.Value + 50, _startPosY.Value + 65, 10, 10); + g.FillEllipse(additionalBrush, _startPosX.Value + 145, _startPosY.Value + 65, 10, 10); // корпус Brush br = new SolidBrush(EntityPlane.BodyColor); g.DrawRectangle(pen, _startPosX.Value, _startPosY.Value + 25, 170, 30); diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs index 6a010fa..aecfeea 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs @@ -118,6 +118,7 @@ ButtonCreatePlane.TabIndex = 6; ButtonCreatePlane.Text = "Создать самолёт"; ButtonCreatePlane.UseVisualStyleBackColor = true; + ButtonCreatePlane.Click += ButtonCreatePlane_Click; // // comboBoxStrategy // @@ -137,7 +138,7 @@ buttonStrategyStepS.TabIndex = 8; buttonStrategyStepS.Text = "Шаг"; buttonStrategyStepS.UseVisualStyleBackColor = true; - buttonStrategyStepS.Click += buttonStrategyStepS_Click; + buttonStrategyStepS.Click += ButtonStrategyStep_Click; // // FormAirPlane // diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs index 9620e4b..355bcff 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs @@ -1,6 +1,7 @@ using ProjectAirPlane.Drawnings; using ProjectAirPlane.MovementStrategy; + namespace ProjectAirPlane; /// @@ -130,12 +131,9 @@ public partial class FormAirPlane : Form /// /// /// - private void buttonStrategyStepS_Click(object sender, EventArgs e) + private void ButtonStrategyStep_Click(object sender, EventArgs e) { - if (_drawningPlane == null) - { - return; - } + if (_drawningPlane == null) return; if (comboBoxStrategy.Enabled) { @@ -149,7 +147,7 @@ public partial class FormAirPlane : Form { return; } - _strategy.SetData(new MoveablePlane(_drawningPlane), pictureBoxAirPlane.Height, pictureBoxAirPlane.Width); + _strategy.SetData(new MoveablePlane(_drawningPlane), pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); } if (_strategy == null) @@ -167,4 +165,6 @@ public partial class FormAirPlane : Form _strategy = null; } } + + } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs index 3619424..51bec7c 100644 --- a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/IMoveableObject.cs @@ -21,4 +21,6 @@ public interface IMoveableObject /// Направление /// true - объект перемещен, false - перемещение невозможно bool TryMoveObject(MovementDirection direction); + + protected void Move(); } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs index 14c1e41..f2dfc0d 100644 --- a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveToCenter.cs @@ -1,5 +1,5 @@ -namespace ProjectAirPlane.MovementStrategy; - + +namespace ProjectAirPlane.MovementStrategy; /// /// Стратегия перемещения объекта в центр экрана @@ -13,11 +13,9 @@ public class MoveToCenter : AbstractStrategy { return false; } - return objParams.ObjectMiddleHorizontal - GetStep() <= FieldWidth / 2 && objParams.ObjectMiddleHorizontal + GetStep() >= FieldWidth / 2 && - objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; + objParams.ObjectMiddleVertical - GetStep() <= FieldHeight / 2 && objParams.ObjectMiddleVertical + GetStep() >= FieldHeight / 2; } - protected override void MoveToTarget() { ObjectParameters? objParams = GetObjectParameters; @@ -25,7 +23,6 @@ public class MoveToCenter : AbstractStrategy { return; } - int diffX = objParams.ObjectMiddleHorizontal - FieldWidth / 2; if (Math.Abs(diffX) > GetStep()) { @@ -38,7 +35,6 @@ public class MoveToCenter : AbstractStrategy MoveRight(); } } - int diffY = objParams.ObjectMiddleVertical - FieldHeight / 2; if (Math.Abs(diffY) > GetStep()) { @@ -53,3 +49,4 @@ public class MoveToCenter : AbstractStrategy } } } + diff --git a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs index 4bc85a1..343743b 100644 --- a/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/MovementStrategy/MoveablePlane.cs @@ -58,4 +58,9 @@ public class MoveablePlane : IMoveableObject _ => DirectionType.Unknow, }; } + + void IMoveableObject.Move() + { + throw new NotImplementedException(); + } } -- 2.25.1 From 9c244adfba3896433a2bb83c4064c239be724eef Mon Sep 17 00:00:00 2001 From: alhimek17 Date: Sun, 24 Mar 2024 17:42:31 +0400 Subject: [PATCH 4/7] =?UTF-8?q?=D0=9A=D0=BE=D0=BC=D0=BF=D0=B0=D0=BD=D0=B8?= =?UTF-8?q?=D1=8F?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractCompany.cs | 100 ++++++++++ .../ICollectionGenericObjects.cs | 49 +++++ .../MassiveGenericObjects.cs | 86 +++++++++ .../PlaneSharigService.cs | 21 +++ .../ProjectAirPlane/FormAirPlane.Designer.cs | 28 --- .../ProjectAirPlane/FormAirPlane.cs | 48 +---- .../FormPlaneCollection.Designer.cs | 177 ++++++++++++++++++ .../ProjectAirPlane/FormPlaneCollection.cs | 175 +++++++++++++++++ .../ProjectAirPlane/FormPlaneCollection.resx | 120 ++++++++++++ ProjectAirPlane/ProjectAirPlane/Program.cs | 2 +- 10 files changed, 731 insertions(+), 75 deletions(-) create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.resx diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs new file mode 100644 index 0000000..3a34be8 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs @@ -0,0 +1,100 @@ +using ProjectAirPlane.Drawnings; + +namespace ProjectAirPlane.CollectionGenericObjects; + +public abstract class AbstractCompany +{ + /// + /// Размер места (ширина) + /// + protected readonly int _placeSizeWidth = 210; + /// + /// Размер места (высота) + /// + protected readonly int _placeSizeHeight = 80; + /// + /// Ширина окна + /// + protected readonly int _pictureWidth; + /// + /// Высота окна + /// + protected readonly int _pictureHeight; + /// + /// Коллекция судов + /// + protected ICollectionGenericObjects? _collection = null; + /// + /// Вычисление максимального количества элементов, который можно разместить в окне + /// + private int GetMaxCount => _pictureWidth * _pictureHeight / (_placeSizeWidth * _placeSizeHeight); + /// + /// Конструктор + /// + /// Ширина окна + /// Высота окна + /// Коллекция автомобилей + public AbstractCompany(int picWidth, int picHeight, ICollectionGenericObjects collection) + { + _pictureWidth = picWidth; + _pictureHeight = picHeight; + _collection = collection; + _collection.SetMaxCount = GetMaxCount; + } + /// + /// Перегрузка оператора сложения для класса + /// + /// Компания + /// Добавляемый объект + /// + public static int operator +(AbstractCompany company, DrawningPlane plane) + { + return company._collection.Insert(plane); + } + /// + /// Перегрузка оператора удаления для класса + /// + /// Компания + /// Номер удаляемого объекта + /// + public static DrawningPlane operator -(AbstractCompany company, int position) + { + return company._collection?.Remove(position); + } + /// + /// Получение случайного объекта из коллекции + /// + /// + public DrawningPlane? GetRandomObject() + { + Random rnd = new(); + return _collection?.Get(rnd.Next(GetMaxCount)); + } + /// + /// Вывод всей коллекции + /// + /// + public Bitmap? Show() + { + Bitmap bitmap = new(_pictureWidth, _pictureHeight); + Graphics graphics = Graphics.FromImage(bitmap); + DrawBackgound(graphics); + SetObjectsPosition(); + for (int i = 0; i < (_collection?.Count ?? 0); ++i) + { + DrawningPlane? obj = _collection?.Get(i); + obj?.DrawTransport(graphics); + } + return bitmap; + } + /// + /// Вывод заднего фона + /// + /// + protected abstract void DrawBackgound(Graphics g); + /// + /// Расстановка объектов + /// + protected abstract void SetObjectsPosition(); +} + diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs new file mode 100644 index 0000000..dc51cd5 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs @@ -0,0 +1,49 @@ +namespace ProjectAirPlane.CollectionGenericObjects; + +/// +/// Интерфейс описания действий для набора хранимых объектов +/// +/// Параметр: ограничение - ссылочный тип +public interface ICollectionGenericObjects + where T : class +{ + /// + /// Количество объектов в коллекции + /// + int Count { get; } + + /// + /// Установка максимального количества элементов + /// + int SetMaxCount { set; } + + /// + /// Добавление объекта в коллекцию + /// + /// Добавляемый объект + /// true - вставка прошла удачно, false - вставка не удалась + int Insert(T obj); + + /// + /// Добавление объекта в коллекцию на конкретную позицию + /// + /// Добавляемый объект + /// Позиция + /// true - вставка прошла удачно, false - вставка не удалась + int Insert(T obj, int position); + + /// + /// Удаление объекта из коллекции с конкретной позиции + /// + /// Позиция + /// true - удаление прошло удачно, false - удаление не удалось + T Remove(int position); + + /// + /// Получение объекта по позиции + /// + /// Позиция + /// Объект + T? Get(int position); +} + diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs new file mode 100644 index 0000000..0820610 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs @@ -0,0 +1,86 @@ +namespace ProjectAirPlane.CollectionGenericObjects; + +public class MassiveGenericObjects : ICollectionGenericObjects + where T : class +{ + /// + /// Массив объектов, которые храним + /// + private T?[] _collection; + public int Count => _collection.Length; + public int SetMaxCount { set { if (value > 0) { _collection = new T?[value]; } } } + /// + /// Конструктор + /// + public MassiveGenericObjects() + { + _collection = Array.Empty(); + } + public T? Get(int position) + { + // TODO проверка позиции + if (position >= _collection.Length || position < 0) return null; + return _collection[position]; + } + public int Insert(T obj) + { + // TODO вставка в свободное место набора + int index = 0; + while (index < _collection.Length) + { + if (_collection[index] == null) + { + _collection[index] = obj; + return index; + } + ++index; + } + return -1; + } + public int Insert(T obj, int position) + { + // TODO проверка позиции + // TODO проверка, что элемент массива по этой позиции пустой, если нет, то + // ищется свободное место после этой позиции и идет вставка туда + // если нет после, ищем до + // TODO вставка + if (position >= _collection.Length || position < 0) + return -1; + if (_collection[position] == null) + { + _collection[position] = obj; + return position; + } + int index = position + 1; + while (index < _collection.Length) + { + if (_collection[index] == null) + { + _collection[index] = obj; + return index; + } + ++index; + } + index = position - 1; + while (index >= 0) + { + if (_collection[index] == null) + { + _collection[index] = obj; + return index; + } + --index; + } + return -1; + } + public T Remove(int position) + { + // TODO проверка позиции + // TODO удаление объекта из массива, присвоив элементу массива значение null + if (position >= _collection.Length || position < 0) + return null; + T obj = _collection[position]; + _collection[position] = null; + return obj; + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs new file mode 100644 index 0000000..b0e0b8b --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs @@ -0,0 +1,21 @@ + +using ProjectAirPlane.Drawnings; + +namespace ProjectAirPlane.CollectionGenericObjects; + +public class PlaneSharigService : AbstractCompany +{ + public PlaneSharigService(int picWidth, int picHeight, ICollectionGenericObjects collection) : base(picWidth, picHeight, collection) + { + } + + protected override void DrawBackgound(Graphics g) + { + throw new NotImplementedException(); + } + + protected override void SetObjectsPosition() + { + throw new NotImplementedException(); + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs index aecfeea..42ee3eb 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.Designer.cs @@ -30,12 +30,10 @@ { System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(FormAirPlane)); pictureBoxAirPlane = new PictureBox(); - buttonCreateAirPlane = new Button(); buttonLeft = new Button(); buttonUp = new Button(); buttonDown = new Button(); buttonRight = new Button(); - ButtonCreatePlane = new Button(); comboBoxStrategy = new ComboBox(); buttonStrategyStepS = new Button(); ((System.ComponentModel.ISupportInitialize)pictureBoxAirPlane).BeginInit(); @@ -50,17 +48,6 @@ pictureBoxAirPlane.TabIndex = 0; pictureBoxAirPlane.TabStop = false; // - // buttonCreateAirPlane - // - buttonCreateAirPlane.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - buttonCreateAirPlane.Location = new Point(12, 488); - buttonCreateAirPlane.Name = "buttonCreateAirPlane"; - buttonCreateAirPlane.Size = new Size(180, 23); - buttonCreateAirPlane.TabIndex = 1; - buttonCreateAirPlane.Text = "Создать самолёт с радаром"; - buttonCreateAirPlane.UseVisualStyleBackColor = true; - buttonCreateAirPlane.Click += ButtonCreateAirPlane_Click; - // // buttonLeft // buttonLeft.Anchor = AnchorStyles.Bottom | AnchorStyles.Right; @@ -109,17 +96,6 @@ buttonRight.UseVisualStyleBackColor = true; buttonRight.Click += ButtonMove_Click; // - // ButtonCreatePlane - // - ButtonCreatePlane.Anchor = AnchorStyles.Bottom | AnchorStyles.Left; - ButtonCreatePlane.Location = new Point(198, 488); - ButtonCreatePlane.Name = "ButtonCreatePlane"; - ButtonCreatePlane.Size = new Size(180, 23); - ButtonCreatePlane.TabIndex = 6; - ButtonCreatePlane.Text = "Создать самолёт"; - ButtonCreatePlane.UseVisualStyleBackColor = true; - ButtonCreatePlane.Click += ButtonCreatePlane_Click; - // // comboBoxStrategy // comboBoxStrategy.DropDownStyle = ComboBoxStyle.DropDownList; @@ -147,12 +123,10 @@ ClientSize = new Size(749, 523); Controls.Add(buttonStrategyStepS); Controls.Add(comboBoxStrategy); - Controls.Add(ButtonCreatePlane); Controls.Add(buttonRight); Controls.Add(buttonDown); Controls.Add(buttonUp); Controls.Add(buttonLeft); - Controls.Add(buttonCreateAirPlane); Controls.Add(pictureBoxAirPlane); Name = "FormAirPlane"; Text = "Спортивный автомобиль"; @@ -163,12 +137,10 @@ #endregion private PictureBox pictureBoxAirPlane; - private Button buttonCreateAirPlane; private Button buttonLeft; private Button buttonUp; private Button buttonDown; private Button buttonRight; - private Button ButtonCreatePlane; private ComboBox comboBoxStrategy; private Button buttonStrategyStepS; } diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs index 355bcff..bad1e30 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs @@ -19,6 +19,8 @@ public partial class FormAirPlane : Form /// private AbstractStrategy? _strategy; + public DrawningPlane SetPlane { get; internal set; } + /// /// /// @@ -44,52 +46,6 @@ public partial class FormAirPlane : Form pictureBoxAirPlane.Image = bmp; } - /// - /// - - /// - /// - private void CreateObject(string type) - { - Random random = new(); - switch (type) - { - case nameof(DrawningPlane): - _drawningPlane = new DrawningPlane(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(DrawningAirPlane): - _drawningPlane = new DrawningAirPlane(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; - } - - _drawningPlane.SetPictureSize(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); - _drawningPlane.SetPosition(random.Next(10, 100), random.Next(10, 100)); - _strategy = null; - comboBoxStrategy.Enabled = true; - Draw(); - } - - /// - /// " " - /// - /// - /// - private void ButtonCreateAirPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningAirPlane)); - - /// - /// " " - /// - /// - /// - private void ButtonCreatePlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningPlane)); - - - /// /// ( ) /// diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs new file mode 100644 index 0000000..947f70f --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs @@ -0,0 +1,177 @@ +namespace ProjectAirPlane +{ + partial class FormPlaneCollection + { + /// + /// Required designer variable. + /// + private System.ComponentModel.IContainer components = null; + + /// + /// Clean up any resources being used. + /// + /// true if managed resources should be disposed; otherwise, false. + protected override void Dispose(bool disposing) + { + if (disposing && (components != null)) + { + components.Dispose(); + } + base.Dispose(disposing); + } + + #region Windows Form Designer generated code + + /// + /// Required method for Designer support - do not modify + /// the contents of this method with the code editor. + /// + private void InitializeComponent() + { + groupBoxTools = new GroupBox(); + buttonRefresh = new Button(); + buttonGoToCheck = new Button(); + buttonRemovePlane = new Button(); + maskedTextBox = new MaskedTextBox(); + buttonAddAirPlane = new Button(); + buttonAddPlane = new Button(); + comboBoxSelectionCompany = new ComboBox(); + pictureBox = new PictureBox(); + groupBoxTools.SuspendLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit(); + SuspendLayout(); + // + // groupBoxTools + // + groupBoxTools.Controls.Add(buttonRefresh); + groupBoxTools.Controls.Add(buttonGoToCheck); + groupBoxTools.Controls.Add(buttonRemovePlane); + groupBoxTools.Controls.Add(maskedTextBox); + groupBoxTools.Controls.Add(buttonAddAirPlane); + groupBoxTools.Controls.Add(buttonAddPlane); + groupBoxTools.Controls.Add(comboBoxSelectionCompany); + groupBoxTools.Dock = DockStyle.Right; + groupBoxTools.Location = new Point(726, 0); + groupBoxTools.Name = "groupBoxTools"; + groupBoxTools.Size = new Size(205, 557); + groupBoxTools.TabIndex = 0; + groupBoxTools.TabStop = false; + groupBoxTools.Text = "Инструменты"; + // + // buttonRefresh + // + buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonRefresh.Location = new Point(6, 484); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(186, 50); + buttonRefresh.TabIndex = 6; + buttonRefresh.Text = "Обновить"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += buttonRefresh_Click; + // + // buttonGoToCheck + // + buttonGoToCheck.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonGoToCheck.Location = new Point(6, 397); + buttonGoToCheck.Name = "buttonGoToCheck"; + buttonGoToCheck.Size = new Size(186, 50); + buttonGoToCheck.TabIndex = 5; + buttonGoToCheck.Text = "Передать на тесты"; + buttonGoToCheck.UseVisualStyleBackColor = true; + buttonGoToCheck.Click += ButtonGoToCheck_Click; + // + // buttonRemovePlane + // + buttonRemovePlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonRemovePlane.Location = new Point(6, 310); + buttonRemovePlane.Name = "buttonRemovePlane"; + buttonRemovePlane.Size = new Size(186, 50); + buttonRemovePlane.TabIndex = 4; + buttonRemovePlane.Text = "Удалить самолёта"; + buttonRemovePlane.UseVisualStyleBackColor = true; + buttonRemovePlane.Click += ButtonRemovePlane_Click; + // + // maskedTextBox + // + maskedTextBox.Location = new Point(6, 281); + maskedTextBox.Mask = "00"; + maskedTextBox.Name = "maskedTextBox"; + maskedTextBox.Size = new Size(186, 23); + maskedTextBox.TabIndex = 3; + maskedTextBox.ValidatingType = typeof(int); + // + // buttonAddAirPlane + // + buttonAddAirPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonAddAirPlane.Location = new Point(6, 143); + buttonAddAirPlane.Name = "buttonAddAirPlane"; + buttonAddAirPlane.Size = new Size(186, 50); + buttonAddAirPlane.TabIndex = 2; + buttonAddAirPlane.Text = "Добавление самолёта с радаром"; + buttonAddAirPlane.UseVisualStyleBackColor = true; + buttonAddAirPlane.Click += ButtonAddAirPlane_Click; + // + // buttonAddPlane + // + buttonAddPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonAddPlane.Location = new Point(6, 87); + buttonAddPlane.Name = "buttonAddPlane"; + buttonAddPlane.Size = new Size(186, 50); + buttonAddPlane.TabIndex = 1; + buttonAddPlane.Text = "Добавление самолёта"; + buttonAddPlane.UseVisualStyleBackColor = true; + buttonAddPlane.Click += ButtonAddPlane_Click; + // + // comboBoxSelectionCompany + // + comboBoxSelectionCompany.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + comboBoxSelectionCompany.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxSelectionCompany.FormattingEnabled = true; + comboBoxSelectionCompany.Items.AddRange(new object[] { "Хранилище" }); + comboBoxSelectionCompany.Location = new Point(6, 22); + comboBoxSelectionCompany.Name = "comboBoxSelectionCompany"; + comboBoxSelectionCompany.Size = new Size(186, 23); + comboBoxSelectionCompany.TabIndex = 0; + // + // pictureBox + // + pictureBox.Dock = DockStyle.Fill; + pictureBox.Location = new Point(0, 0); + pictureBox.Name = "pictureBox"; + pictureBox.Size = new Size(726, 557); + pictureBox.TabIndex = 1; + pictureBox.TabStop = false; + // + // FormPlaneCollection + // + AutoScaleDimensions = new SizeF(7F, 15F); + AutoScaleMode = AutoScaleMode.Font; + ClientSize = new Size(931, 557); + Controls.Add(pictureBox); + Controls.Add(groupBoxTools); + Name = "FormPlaneCollection"; + Text = "Коллекция самолётов"; + groupBoxTools.ResumeLayout(false); + groupBoxTools.PerformLayout(); + ((System.ComponentModel.ISupportInitialize)pictureBox).EndInit(); + ResumeLayout(false); + } + + private void ButtonAddPlane_Click1(object sender, EventArgs e) + { + throw new NotImplementedException(); + } + + #endregion + + private GroupBox groupBoxTools; + private ComboBox comboBoxSelectionCompany; + private Button buttonAddPlane; + private Button buttonAddAirPlane; + private PictureBox pictureBox; + private Button buttonRemovePlane; + private MaskedTextBox maskedTextBox; + private Button buttonGoToCheck; + private Button buttonRefresh; + } +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs new file mode 100644 index 0000000..f59deee --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs @@ -0,0 +1,175 @@ +using System; +using System.Collections.Generic; +using System.ComponentModel; +using System.Data; +using System.Drawing; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using System.Windows.Forms; +using ProjectAirPlane.CollectionGenericObjects; +using ProjectAirPlane.Drawnings; + +namespace ProjectAirPlane; + +/// +/// Форма работы с компанией и ее коллекцией +/// +public partial class FormPlaneCollection : Form +{ + /// + /// Компания + /// + private AbstractCompany? _company = null; + + /// + /// Конструктор + /// + public FormPlaneCollection() + { + InitializeComponent(); + } + + /// + /// Выбор компании + /// + /// + /// + private void ComboBoxSelectionCompany_SelectedIndexChanged(object sender, EventArgs e) + { + switch (comboBoxSelectionCompany.Text) + { + case "Хранилище": + _company = new PlaneSharigService(pictureBox.Width, pictureBox.Height, new MassiveGenericObjects()); + break; + } + } + + /// + /// Создание объекта класса-перемещения + /// + /// Тип создаваемого объекта + private void CreateObject(string type) + { + DrawningPlane drawningPlane; + if (_company == null) + { + return; + } + + Random random = new(); + switch (type) + { + case nameof(DrawningPlane): + drawningPlane = new DrawningPlane(random.Next(100, 300), random.Next(1000, 3000), GetColor(random)); + break; + case nameof(DrawningAirPlane): + drawningPlane = new DrawningAirPlane(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; + } + + if (_company + drawningPlane != -1) + { + MessageBox.Show("Объект добавлен"); + pictureBox.Image = _company.Show(); + } + else + { + MessageBox.Show("Не удалось добавить объект"); + } + } + /// + /// Получение цвета + /// + /// Генератор случайных чисел + /// + private static Color GetColor(Random random) + { + Color color = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)); + ColorDialog dialog = new(); + if (dialog.ShowDialog() == DialogResult.OK) + { + color = dialog.Color; + } + return color; + } + + private void ButtonAddPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningPlane)); + + + private void ButtonAddAirPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningAirPlane)); + + /// + /// Удаление объекта + /// + /// + /// + private void ButtonRemovePlane_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(maskedTextBox.Text) || _company == null) + { + return; + } + if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) + { + return; + } + int pos = Convert.ToInt32(maskedTextBox.Text); + if (_company - pos != null) + { + MessageBox.Show("Объект удален"); + pictureBox.Image = _company.Show(); + } + else + { + MessageBox.Show("Не удалось удалить объект"); + } + } + + /// + /// Передача объекта в другую форму + /// + /// + /// + private void ButtonGoToCheck_Click(object sender, EventArgs e) + { + if (_company == null) + { + return; + } + DrawningPlane? plane = null; + int counter = 100; + while (plane == null) + { + plane = _company.GetRandomObject(); + counter--; + if (counter <= 0) + { + break; + } + } + if (plane == null) + { + return; + } + FormAirPlane form = new() + { + SetPlane = plane + }; + form.ShowDialog(); + } + + private void buttonRefresh_Click(object sender, EventArgs e) + { + if (_company == null) + { + return; + } + pictureBox.Image = _company.Show(); + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.resx b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.resx new file mode 100644 index 0000000..af32865 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.resx @@ -0,0 +1,120 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + text/microsoft-resx + + + 2.0 + + + System.Resources.ResXResourceReader, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + + System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089 + + \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/Program.cs b/ProjectAirPlane/ProjectAirPlane/Program.cs index 37a9525..bd0c956 100644 --- a/ProjectAirPlane/ProjectAirPlane/Program.cs +++ b/ProjectAirPlane/ProjectAirPlane/Program.cs @@ -11,7 +11,7 @@ namespace ProjectAirPlane // To customize application configuration such as set high DPI settings or default font, // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); - Application.Run(new FormAirPlane()); + Application.Run(new FormPlaneCollection()); } } } \ No newline at end of file -- 2.25.1 From 2bec551f18ae59012cae4d6535600a34a1f7eb57 Mon Sep 17 00:00:00 2001 From: alhimek17 Date: Sun, 24 Mar 2024 19:22:18 +0400 Subject: [PATCH 5/7] =?UTF-8?q?=D0=9F=D1=80=D0=B0=D0=BA=D1=82=D0=B8=D1=87?= =?UTF-8?q?=D0=B5=D1=81=D0=BA=D0=B8=20=D0=B4=D0=BE=D0=B4=D0=B5=D0=BB=D0=B0?= =?UTF-8?q?=D0=BD=D0=BD=D0=B0=D1=8F=20=D0=9B=D0=B0=D0=B1=20=D1=80=D0=B0?= =?UTF-8?q?=D0=B1=D0=BE=D1=82=D0=B0=2003?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractCompany.cs | 4 +- .../PlaneSharigService.cs | 41 ++++++++++++++++++- .../FormPlaneCollection.Designer.cs | 2 +- 3 files changed, 42 insertions(+), 5 deletions(-) diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs index 3a34be8..a705d97 100644 --- a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs @@ -7,11 +7,11 @@ public abstract class AbstractCompany /// /// Размер места (ширина) /// - protected readonly int _placeSizeWidth = 210; + protected readonly int _placeSizeWidth = 195; /// /// Размер места (высота) /// - protected readonly int _placeSizeHeight = 80; + protected readonly int _placeSizeHeight = 70; /// /// Ширина окна /// diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs index b0e0b8b..0fccf19 100644 --- a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs @@ -11,11 +11,48 @@ public class PlaneSharigService : AbstractCompany protected override void DrawBackgound(Graphics g) { - throw new NotImplementedException(); + + Pen pen = new(Color.Black, 3); + for (int i = 0; i < _pictureWidth / _placeSizeWidth; i++) + { + for (int j = 0; j < _pictureHeight / _placeSizeHeight + + 1; ++j) + { + g.DrawLine(pen, i * _placeSizeWidth, j * + _placeSizeHeight, i * _placeSizeWidth + _placeSizeWidth / 2, j * + _placeSizeHeight); + } + g.DrawLine(pen, i * _placeSizeWidth, 0, i * + _placeSizeWidth, _pictureHeight / _placeSizeHeight * _placeSizeHeight); + } } protected override void SetObjectsPosition() { - throw new NotImplementedException(); + int width = _pictureWidth / _placeSizeWidth; + int height = _pictureHeight / _placeSizeHeight; + + int curWidth = width - 1; + int curHeight = 0; + + for (int i = 0; i < (_collection?.Count ?? 0); i++) + { + if (_collection.Get(i) != null) + { + _collection.Get(i).SetPictureSize(_pictureWidth, _pictureHeight); + _collection.Get(i).SetPosition(_placeSizeWidth * curWidth + 20, curHeight * _placeSizeHeight + 4); + } + if (curWidth > 0) + curWidth--; + else + { + curWidth = width - 1; + curHeight++; + } + if (curHeight > height) + { + return; + } + } } } diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs index 947f70f..ae38492 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs @@ -118,7 +118,7 @@ buttonAddPlane.Name = "buttonAddPlane"; buttonAddPlane.Size = new Size(186, 50); buttonAddPlane.TabIndex = 1; - buttonAddPlane.Text = "Добавление самолёта"; + buttonAddPlane.Text = "Добавление судна"; buttonAddPlane.UseVisualStyleBackColor = true; buttonAddPlane.Click += ButtonAddPlane_Click; // -- 2.25.1 From 8f24090bdf845dee672b330cb7a27d8ec787ae63 Mon Sep 17 00:00:00 2001 From: alhimek17 Date: Tue, 26 Mar 2024 13:14:52 +0400 Subject: [PATCH 6/7] =?UTF-8?q?=D0=9B=D0=B0=D0=B1=D0=BE=D1=80=D0=B0=D1=82?= =?UTF-8?q?=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE=D1=82?= =?UTF-8?q?=D0=B0=20=E2=84=963?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../AbstractCompany.cs | 38 +++++++--- .../ICollectionGenericObjects.cs | 15 ++-- .../MassiveGenericObjects.cs | 54 ++++++++++++--- ...harigService.cs => PlaneSharingService.cs} | 27 ++++---- .../ProjectAirPlane/FormAirPlane.cs | 35 ++++++---- .../FormPlaneCollection.Designer.cs | 69 +++++++++---------- .../ProjectAirPlane/FormPlaneCollection.cs | 59 ++++++++-------- ProjectAirPlane/ProjectAirPlane/Program.cs | 1 + 8 files changed, 180 insertions(+), 118 deletions(-) rename ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/{PlaneSharigService.cs => PlaneSharingService.cs} (58%) diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs index a705d97..5788d0b 100644 --- a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/AbstractCompany.cs @@ -1,33 +1,44 @@ -using ProjectAirPlane.Drawnings; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using ProjectAirPlane.Drawnings; namespace ProjectAirPlane.CollectionGenericObjects; public abstract class AbstractCompany { /// - /// Размер места (ширина) - /// - protected readonly int _placeSizeWidth = 195; + /// Размер места (ширина) + /// + protected readonly int _placeSizeWidth = 210; + /// /// Размер места (высота) /// - protected readonly int _placeSizeHeight = 70; + protected readonly int _placeSizeHeight = 80; + /// /// Ширина окна /// protected readonly int _pictureWidth; + /// /// Высота окна /// protected readonly int _pictureHeight; + /// - /// Коллекция судов + /// Коллекция автомобилей /// protected ICollectionGenericObjects? _collection = null; + /// /// Вычисление максимального количества элементов, который можно разместить в окне /// private int GetMaxCount => _pictureWidth * _pictureHeight / (_placeSizeWidth * _placeSizeHeight); + /// /// Конструктор /// @@ -41,16 +52,18 @@ public abstract class AbstractCompany _collection = collection; _collection.SetMaxCount = GetMaxCount; } + /// /// Перегрузка оператора сложения для класса /// /// Компания - /// Добавляемый объект + /// Добавляемый объект /// public static int operator +(AbstractCompany company, DrawningPlane plane) { - return company._collection.Insert(plane); + return company._collection?.Insert(plane) ?? -1; } + /// /// Перегрузка оператора удаления для класса /// @@ -59,8 +72,9 @@ public abstract class AbstractCompany /// public static DrawningPlane operator -(AbstractCompany company, int position) { - return company._collection?.Remove(position); + return company._collection?.Remove(position) ?? null; } + /// /// Получение случайного объекта из коллекции /// @@ -70,6 +84,7 @@ public abstract class AbstractCompany Random rnd = new(); return _collection?.Get(rnd.Next(GetMaxCount)); } + /// /// Вывод всей коллекции /// @@ -79,22 +94,25 @@ public abstract class AbstractCompany Bitmap bitmap = new(_pictureWidth, _pictureHeight); Graphics graphics = Graphics.FromImage(bitmap); DrawBackgound(graphics); + SetObjectsPosition(); for (int i = 0; i < (_collection?.Count ?? 0); ++i) { DrawningPlane? obj = _collection?.Get(i); obj?.DrawTransport(graphics); } + return bitmap; } + /// /// Вывод заднего фона /// /// protected abstract void DrawBackgound(Graphics g); + /// /// Расстановка объектов /// protected abstract void SetObjectsPosition(); } - diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs index dc51cd5..d609f17 100644 --- a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ICollectionGenericObjects.cs @@ -1,9 +1,11 @@ -namespace ProjectAirPlane.CollectionGenericObjects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectAirPlane.CollectionGenericObjects; -/// -/// Интерфейс описания действий для набора хранимых объектов -/// -/// Параметр: ограничение - ссылочный тип public interface ICollectionGenericObjects where T : class { @@ -37,7 +39,7 @@ public interface ICollectionGenericObjects ///
/// Позиция /// true - удаление прошло удачно, false - удаление не удалось - T Remove(int position); + T? Remove(int position); /// /// Получение объекта по позиции @@ -46,4 +48,3 @@ public interface ICollectionGenericObjects /// Объект T? Get(int position); } - diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs index 0820610..32c4e8f 100644 --- a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/MassiveGenericObjects.cs @@ -1,27 +1,54 @@ -namespace ProjectAirPlane.CollectionGenericObjects; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectAirPlane.CollectionGenericObjects; public class MassiveGenericObjects : ICollectionGenericObjects where T : class { /// - /// Массив объектов, которые храним - /// - private T?[] _collection; + /// Массив объектов, которые храним + /// + private T?[] _collection; + public int Count => _collection.Length; - public int SetMaxCount { set { if (value > 0) { _collection = new T?[value]; } } } + + public int SetMaxCount + { + set + { + if (value > 0) + { + if (_collection.Length > 0) + { + Array.Resize(ref _collection, value); + } + else + { + _collection = new T?[value]; + } + } + } + } + /// - /// Конструктор - /// - public MassiveGenericObjects() + /// Конструктор + ///
+ public MassiveGenericObjects() { _collection = Array.Empty(); } + public T? Get(int position) { // TODO проверка позиции if (position >= _collection.Length || position < 0) return null; return _collection[position]; } + public int Insert(T obj) { // TODO вставка в свободное место набора @@ -37,12 +64,13 @@ public class MassiveGenericObjects : ICollectionGenericObjects } return -1; } + public int Insert(T obj, int position) { // TODO проверка позиции // TODO проверка, что элемент массива по этой позиции пустой, если нет, то - // ищется свободное место после этой позиции и идет вставка туда - // если нет после, ищем до + // ищется свободное место после этой позиции и идет вставка туда + // если нет после, ищем до // TODO вставка if (position >= _collection.Length || position < 0) return -1; @@ -73,14 +101,18 @@ public class MassiveGenericObjects : ICollectionGenericObjects } return -1; } + public T Remove(int position) { // TODO проверка позиции // TODO удаление объекта из массива, присвоив элементу массива значение null if (position >= _collection.Length || position < 0) + { return null; + } + T obj = _collection[position]; _collection[position] = null; return obj; } -} \ No newline at end of file +} diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharingService.cs similarity index 58% rename from ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs rename to ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharingService.cs index 0fccf19..2b20d90 100644 --- a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharigService.cs +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/PlaneSharingService.cs @@ -1,29 +1,30 @@ - +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; using ProjectAirPlane.Drawnings; namespace ProjectAirPlane.CollectionGenericObjects; -public class PlaneSharigService : AbstractCompany +public class PlaneSharingService : AbstractCompany { - public PlaneSharigService(int picWidth, int picHeight, ICollectionGenericObjects collection) : base(picWidth, picHeight, collection) + public PlaneSharingService(int picWidth, int picHeight, ICollectionGenericObjects collection) : base(picWidth, picHeight, collection) { } protected override void DrawBackgound(Graphics g) { - + + int width = _pictureWidth / _placeSizeWidth; + int height = _pictureHeight / _placeSizeHeight; Pen pen = new(Color.Black, 3); - for (int i = 0; i < _pictureWidth / _placeSizeWidth; i++) + for (int i = 0; i < width; i++) { - for (int j = 0; j < _pictureHeight / _placeSizeHeight + - 1; ++j) + for (int j = 0; j < height + 1; ++j) { - g.DrawLine(pen, i * _placeSizeWidth, j * - _placeSizeHeight, i * _placeSizeWidth + _placeSizeWidth / 2, j * - _placeSizeHeight); + g.DrawLine(pen, i * _placeSizeWidth, j * _placeSizeHeight, i * _placeSizeWidth + _placeSizeWidth - 5, j * _placeSizeHeight); } - g.DrawLine(pen, i * _placeSizeWidth, 0, i * - _placeSizeWidth, _pictureHeight / _placeSizeHeight * _placeSizeHeight); } } @@ -40,7 +41,7 @@ public class PlaneSharigService : AbstractCompany if (_collection.Get(i) != null) { _collection.Get(i).SetPictureSize(_pictureWidth, _pictureHeight); - _collection.Get(i).SetPosition(_placeSizeWidth * curWidth + 20, curHeight * _placeSizeHeight + 4); + _collection.Get(i).SetPosition(_placeSizeWidth * curWidth + 15, curHeight * _placeSizeHeight + 3); } if (curWidth > 0) curWidth--; diff --git a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs index bad1e30..91510ac 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormAirPlane.cs @@ -3,9 +3,8 @@ using ProjectAirPlane.MovementStrategy; namespace ProjectAirPlane; - /// -/// " " +/// "" /// public partial class FormAirPlane : Form { @@ -15,11 +14,21 @@ public partial class FormAirPlane : Form private DrawningPlane? _drawningPlane; /// - /// - /// - private AbstractStrategy? _strategy; + /// + ///
+ private AbstractStrategy? _strategy; - public DrawningPlane SetPlane { get; internal set; } + public DrawningPlane SetPlane + { + set + { + _drawningPlane = value; + _drawningPlane.SetPictureSize(pictureBoxAirPlane.Width, pictureBoxAirPlane.Height); + comboBoxStrategy.Enabled = true; + _strategy = null; + Draw(); + } + } /// /// @@ -31,7 +40,7 @@ public partial class FormAirPlane : Form } /// - /// + /// /// private void Draw() { @@ -83,11 +92,11 @@ public partial class FormAirPlane : Form } /// - /// "" - /// - /// - /// - private void ButtonStrategyStep_Click(object sender, EventArgs e) + /// + /// + /// + /// + private void ButtonStrategyStep_Click(object sender, EventArgs e) { if (_drawningPlane == null) return; @@ -121,6 +130,4 @@ public partial class FormAirPlane : Form _strategy = null; } } - - } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs index ae38492..ec8bb03 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs @@ -35,7 +35,7 @@ maskedTextBox = new MaskedTextBox(); buttonAddAirPlane = new Button(); buttonAddPlane = new Button(); - comboBoxSelectionCompany = new ComboBox(); + comboBoxSelectorCompany = new ComboBox(); pictureBox = new PictureBox(); groupBoxTools.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit(); @@ -49,11 +49,11 @@ groupBoxTools.Controls.Add(maskedTextBox); groupBoxTools.Controls.Add(buttonAddAirPlane); groupBoxTools.Controls.Add(buttonAddPlane); - groupBoxTools.Controls.Add(comboBoxSelectionCompany); + groupBoxTools.Controls.Add(comboBoxSelectorCompany); groupBoxTools.Dock = DockStyle.Right; - groupBoxTools.Location = new Point(726, 0); + groupBoxTools.Location = new Point(686, 0); groupBoxTools.Name = "groupBoxTools"; - groupBoxTools.Size = new Size(205, 557); + groupBoxTools.Size = new Size(195, 513); groupBoxTools.TabIndex = 0; groupBoxTools.TabStop = false; groupBoxTools.Text = "Инструменты"; @@ -61,20 +61,20 @@ // buttonRefresh // buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonRefresh.Location = new Point(6, 484); + buttonRefresh.Location = new Point(6, 417); buttonRefresh.Name = "buttonRefresh"; - buttonRefresh.Size = new Size(186, 50); + buttonRefresh.Size = new Size(177, 35); buttonRefresh.TabIndex = 6; buttonRefresh.Text = "Обновить"; buttonRefresh.UseVisualStyleBackColor = true; - buttonRefresh.Click += buttonRefresh_Click; + buttonRefresh.Click += ButtonRefresh_Click; // // buttonGoToCheck // buttonGoToCheck.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonGoToCheck.Location = new Point(6, 397); + buttonGoToCheck.Location = new Point(6, 320); buttonGoToCheck.Name = "buttonGoToCheck"; - buttonGoToCheck.Size = new Size(186, 50); + buttonGoToCheck.Size = new Size(177, 35); buttonGoToCheck.TabIndex = 5; buttonGoToCheck.Text = "Передать на тесты"; buttonGoToCheck.UseVisualStyleBackColor = true; @@ -83,29 +83,30 @@ // buttonRemovePlane // buttonRemovePlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonRemovePlane.Location = new Point(6, 310); + buttonRemovePlane.Location = new Point(7, 255); buttonRemovePlane.Name = "buttonRemovePlane"; - buttonRemovePlane.Size = new Size(186, 50); + buttonRemovePlane.Size = new Size(177, 35); buttonRemovePlane.TabIndex = 4; - buttonRemovePlane.Text = "Удалить самолёта"; + buttonRemovePlane.Text = "Удалить самолёт"; buttonRemovePlane.UseVisualStyleBackColor = true; buttonRemovePlane.Click += ButtonRemovePlane_Click; // // maskedTextBox // - maskedTextBox.Location = new Point(6, 281); + maskedTextBox.Location = new Point(7, 207); maskedTextBox.Mask = "00"; maskedTextBox.Name = "maskedTextBox"; - maskedTextBox.Size = new Size(186, 23); + maskedTextBox.Size = new Size(180, 23); maskedTextBox.TabIndex = 3; maskedTextBox.ValidatingType = typeof(int); + maskedTextBox.MaskInputRejected += MaskedTextBox_MaskInputRejected; // // buttonAddAirPlane // buttonAddAirPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonAddAirPlane.Location = new Point(6, 143); + buttonAddAirPlane.Location = new Point(7, 135); buttonAddAirPlane.Name = "buttonAddAirPlane"; - buttonAddAirPlane.Size = new Size(186, 50); + buttonAddAirPlane.Size = new Size(177, 47); buttonAddAirPlane.TabIndex = 2; buttonAddAirPlane.Text = "Добавление самолёта с радаром"; buttonAddAirPlane.UseVisualStyleBackColor = true; @@ -114,31 +115,32 @@ // buttonAddPlane // buttonAddPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonAddPlane.Location = new Point(6, 87); + buttonAddPlane.Location = new Point(6, 80); buttonAddPlane.Name = "buttonAddPlane"; - buttonAddPlane.Size = new Size(186, 50); + buttonAddPlane.Size = new Size(177, 37); buttonAddPlane.TabIndex = 1; - buttonAddPlane.Text = "Добавление судна"; + buttonAddPlane.Text = "Добавление самолёта"; buttonAddPlane.UseVisualStyleBackColor = true; buttonAddPlane.Click += ButtonAddPlane_Click; // - // comboBoxSelectionCompany + // comboBoxSelectorCompany // - comboBoxSelectionCompany.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - comboBoxSelectionCompany.DropDownStyle = ComboBoxStyle.DropDownList; - comboBoxSelectionCompany.FormattingEnabled = true; - comboBoxSelectionCompany.Items.AddRange(new object[] { "Хранилище" }); - comboBoxSelectionCompany.Location = new Point(6, 22); - comboBoxSelectionCompany.Name = "comboBoxSelectionCompany"; - comboBoxSelectionCompany.Size = new Size(186, 23); - comboBoxSelectionCompany.TabIndex = 0; + comboBoxSelectorCompany.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + comboBoxSelectorCompany.DropDownStyle = ComboBoxStyle.DropDownList; + comboBoxSelectorCompany.FormattingEnabled = true; + comboBoxSelectorCompany.Items.AddRange(new object[] { "Хранилище" }); + comboBoxSelectorCompany.Location = new Point(6, 22); + comboBoxSelectorCompany.Name = "comboBoxSelectorCompany"; + comboBoxSelectorCompany.Size = new Size(178, 23); + comboBoxSelectorCompany.TabIndex = 0; + comboBoxSelectorCompany.SelectedIndexChanged += ComboBoxSelectorCompany_SelectedIndexChanged; // // pictureBox // pictureBox.Dock = DockStyle.Fill; pictureBox.Location = new Point(0, 0); pictureBox.Name = "pictureBox"; - pictureBox.Size = new Size(726, 557); + pictureBox.Size = new Size(686, 513); pictureBox.TabIndex = 1; pictureBox.TabStop = false; // @@ -146,7 +148,7 @@ // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(931, 557); + ClientSize = new Size(881, 513); Controls.Add(pictureBox); Controls.Add(groupBoxTools); Name = "FormPlaneCollection"; @@ -157,15 +159,10 @@ ResumeLayout(false); } - private void ButtonAddPlane_Click1(object sender, EventArgs e) - { - throw new NotImplementedException(); - } - #endregion private GroupBox groupBoxTools; - private ComboBox comboBoxSelectionCompany; + private ComboBox comboBoxSelectorCompany; private Button buttonAddPlane; private Button buttonAddAirPlane; private PictureBox pictureBox; diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs index f59deee..c6e665a 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs @@ -23,24 +23,24 @@ public partial class FormPlaneCollection : Form private AbstractCompany? _company = null; /// - /// Конструктор - /// + /// Конструктор + /// public FormPlaneCollection() { InitializeComponent(); } /// - /// Выбор компании - /// - /// - /// - private void ComboBoxSelectionCompany_SelectedIndexChanged(object sender, EventArgs e) + /// Выбор компании + /// + /// + /// + private void ComboBoxSelectorCompany_SelectedIndexChanged(object sender, EventArgs e) { - switch (comboBoxSelectionCompany.Text) + switch (comboBoxSelectorCompany.Text) { case "Хранилище": - _company = new PlaneSharigService(pictureBox.Width, pictureBox.Height, new MassiveGenericObjects()); + _company = new PlaneSharingService(pictureBox.Width, pictureBox.Height, new MassiveGenericObjects()); break; } } @@ -51,22 +51,22 @@ public partial class FormPlaneCollection : Form /// Тип создаваемого объекта private void CreateObject(string type) { - DrawningPlane drawningPlane; if (_company == null) { return; } Random random = new(); + DrawningPlane drawningPlane; switch (type) { case nameof(DrawningPlane): drawningPlane = new DrawningPlane(random.Next(100, 300), random.Next(1000, 3000), GetColor(random)); break; case nameof(DrawningAirPlane): + // TODO вызов диалогового окна для выбора цвета drawningPlane = new DrawningAirPlane(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)), + GetColor(random), GetColor(random), Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2)), Convert.ToBoolean(random.Next(0, 2))); break; default: @@ -83,12 +83,13 @@ public partial class FormPlaneCollection : Form MessageBox.Show("Не удалось добавить объект"); } } + /// /// Получение цвета /// /// Генератор случайных чисел /// - private static Color GetColor(Random random) + private static Color GetColor(Random random) { Color color = Color.FromArgb(random.Next(0, 256), random.Next(0, 256), random.Next(0, 256)); ColorDialog dialog = new(); @@ -96,29 +97,34 @@ public partial class FormPlaneCollection : Form { color = dialog.Color; } + return color; } - private void ButtonAddPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningPlane)); + + private void ButtonAddAirPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningAirPlane)); + + + private void MaskedTextBox_MaskInputRejected(object sender, MaskInputRejectedEventArgs e) + { + + } - /// - /// Удаление объекта - /// - /// - /// private void ButtonRemovePlane_Click(object sender, EventArgs e) { if (string.IsNullOrEmpty(maskedTextBox.Text) || _company == null) { return; } - if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) + + if (MessageBox.Show("Удалить объект?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) != DialogResult.Yes) { return; } + int pos = Convert.ToInt32(maskedTextBox.Text); if (_company - pos != null) { @@ -131,17 +137,13 @@ public partial class FormPlaneCollection : Form } } - /// - /// Передача объекта в другую форму - /// - /// - /// private void ButtonGoToCheck_Click(object sender, EventArgs e) { if (_company == null) { return; } + DrawningPlane? plane = null; int counter = 100; while (plane == null) @@ -153,10 +155,12 @@ public partial class FormPlaneCollection : Form break; } } + if (plane == null) { return; } + FormAirPlane form = new() { SetPlane = plane @@ -164,12 +168,13 @@ public partial class FormPlaneCollection : Form form.ShowDialog(); } - private void buttonRefresh_Click(object sender, EventArgs e) + private void ButtonRefresh_Click(object sender, EventArgs e) { if (_company == null) { return; } + pictureBox.Image = _company.Show(); - } + } } diff --git a/ProjectAirPlane/ProjectAirPlane/Program.cs b/ProjectAirPlane/ProjectAirPlane/Program.cs index bd0c956..831f9a4 100644 --- a/ProjectAirPlane/ProjectAirPlane/Program.cs +++ b/ProjectAirPlane/ProjectAirPlane/Program.cs @@ -12,6 +12,7 @@ namespace ProjectAirPlane // see https://aka.ms/applicationconfiguration. ApplicationConfiguration.Initialize(); Application.Run(new FormPlaneCollection()); + } } } \ No newline at end of file -- 2.25.1 From 612133fe1d53b22a3f4993b3cc704905a68ad11e Mon Sep 17 00:00:00 2001 From: alhimek17 Date: Mon, 8 Apr 2024 00:48:44 +0400 Subject: [PATCH 7/7] =?UTF-8?q?4=20=D0=BB=D0=B0=D0=B1=D0=BE=D1=80=D0=B0?= =?UTF-8?q?=D1=82=D0=BE=D1=80=D0=BD=D0=B0=D1=8F=20=D1=80=D0=B0=D0=B1=D0=BE?= =?UTF-8?q?=D1=82=D0=B0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../CollectionType.cs | 22 ++ .../ListGenericObjects.cs | 70 +++++ .../StorageCollection.cs | 78 ++++++ .../FormPlaneCollection.Designer.cs | 261 +++++++++++++----- .../ProjectAirPlane/FormPlaneCollection.cs | 116 +++++++- 5 files changed, 471 insertions(+), 76 deletions(-) create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/CollectionType.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ListGenericObjects.cs create mode 100644 ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/StorageCollection.cs diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/CollectionType.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/CollectionType.cs new file mode 100644 index 0000000..d88b9f1 --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/CollectionType.cs @@ -0,0 +1,22 @@ +namespace ProjectAirPlane.CollectionGenericObjects; + +/// +/// Тип коллекции +/// +public enum CollectionType +{ + /// + /// Неопределено + /// + None = 0, + + /// + /// Массив + /// + Massive = 1, + + /// + /// Список + /// + List = 2 +} \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ListGenericObjects.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ListGenericObjects.cs new file mode 100644 index 0000000..f356dfc --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/ListGenericObjects.cs @@ -0,0 +1,70 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace ProjectAirPlane.CollectionGenericObjects; + +public class ListGenericObjects : ICollectionGenericObjects + where T : class +{ + /// + /// Список объектов, которые храним + /// + private readonly List _collection; + + /// + /// Максимально допустимое число объектов в списке + /// + private int _maxCount; + + public int Count => _collection.Count; + + public int SetMaxCount { set { if (value > 0) { _maxCount = value; } } } + + /// + /// Конструктор + /// + public ListGenericObjects() + { + _collection = new(); + } + + public T? Get(int position) + { + // TODO проверка позиции + if (position >= Count || position < 0) return null; + return _collection[position]; + } + + public int Insert(T obj) + { + // TODO проверка, что не превышено максимальное количество элементов + // TODO вставка в конец набора + if (Count == _maxCount) return -1; + _collection.Add(obj); + return Count; + } + + public int Insert(T obj, int position) + { + // TODO проверка, что не превышено максимальное количество элементов + // TODO проверка позиции + // TODO вставка по позиции + if (Count == _maxCount) return -1; + if (position >= Count || position < 0) return -1; + _collection.Insert(position, obj); + return position; + } + + public T Remove(int position) + { + // TODO проверка позиции + // TODO удаление объекта из списка + if (position >= Count || position < 0) return null; + T obj = _collection[position]; + _collection.RemoveAt(position); + return obj; + } +} diff --git a/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/StorageCollection.cs b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/StorageCollection.cs new file mode 100644 index 0000000..d1b2c3d --- /dev/null +++ b/ProjectAirPlane/ProjectAirPlane/CollectionGenericObjects/StorageCollection.cs @@ -0,0 +1,78 @@ +namespace ProjectAirPlane.CollectionGenericObjects; + +/// +/// Класс-хранилище коллекций +/// +/// +public class StorageCollection + where T : class +{ + /// + /// Словарь (хранилище) с коллекциями + /// + readonly Dictionary> _storages; + + /// + /// Возвращение списка названий коллекций + /// + public List Keys => _storages.Keys.ToList(); + + /// + /// Конструктор + /// + public StorageCollection() + { + _storages = new Dictionary>(); + } + + /// + /// Добавление коллекции в хранилище + /// + /// Название коллекции + /// тип коллекции + public void AddCollection(string name, CollectionType collectionType) + { + // TODO проверка, что name не пустой и нет в словаре записи с таким ключом + // TODO Прописать логику для добавления + if (!(collectionType == CollectionType.None) && !_storages.ContainsKey(name)) + { + if (collectionType == CollectionType.List) + { + _storages.Add(name, new ListGenericObjects()); + } + else if (collectionType == CollectionType.Massive) + { + _storages.Add(name, new MassiveGenericObjects()); + } + } + } + + /// + /// Удаление коллекции + /// + /// Название коллекции + public void DelCollection(string name) + { + // TODO Прописать логику для удаления коллекции + if (_storages.ContainsKey(name)) { _storages.Remove(name); } + } + + /// + /// Доступ к коллекции + /// + /// Название коллекции + /// + public ICollectionGenericObjects? this[string name] + { + get + { + // TODO Продумать логику получения объекта + if (_storages.ContainsKey(name)) + { + return _storages[name]; + } + return null; + } + } + +} diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs index ec8bb03..b13da08 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.Designer.cs @@ -29,99 +29,215 @@ private void InitializeComponent() { groupBoxTools = new GroupBox(); - buttonRefresh = new Button(); - buttonGoToCheck = new Button(); - buttonRemovePlane = new Button(); - maskedTextBox = new MaskedTextBox(); - buttonAddAirPlane = new Button(); + panelCompanyTools = new Panel(); buttonAddPlane = new Button(); + buttonAddAirPlane = new Button(); + maskedTextBox = new MaskedTextBox(); + buttonRefresh = new Button(); + buttonRemovePlane = new Button(); + buttonGoToCheck = new Button(); + buttonCreateCompany = new Button(); + panelStorage = new Panel(); + buttonCollectionDel = new Button(); + listBoxCollection = new ListBox(); + buttonCollectionAdd = new Button(); + radioButtonList = new RadioButton(); + radioButtonMassive = new RadioButton(); + textBoxCollectionName = new TextBox(); + labelCollectionName = new Label(); comboBoxSelectorCompany = new ComboBox(); pictureBox = new PictureBox(); groupBoxTools.SuspendLayout(); + panelCompanyTools.SuspendLayout(); + panelStorage.SuspendLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox).BeginInit(); SuspendLayout(); // // groupBoxTools // - groupBoxTools.Controls.Add(buttonRefresh); - groupBoxTools.Controls.Add(buttonGoToCheck); - groupBoxTools.Controls.Add(buttonRemovePlane); - groupBoxTools.Controls.Add(maskedTextBox); - groupBoxTools.Controls.Add(buttonAddAirPlane); - groupBoxTools.Controls.Add(buttonAddPlane); + groupBoxTools.Controls.Add(panelCompanyTools); + groupBoxTools.Controls.Add(buttonCreateCompany); + groupBoxTools.Controls.Add(panelStorage); groupBoxTools.Controls.Add(comboBoxSelectorCompany); groupBoxTools.Dock = DockStyle.Right; groupBoxTools.Location = new Point(686, 0); groupBoxTools.Name = "groupBoxTools"; - groupBoxTools.Size = new Size(195, 513); + groupBoxTools.Size = new Size(195, 558); groupBoxTools.TabIndex = 0; groupBoxTools.TabStop = false; groupBoxTools.Text = "Инструменты"; // - // buttonRefresh + // panelCompanyTools // - buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonRefresh.Location = new Point(6, 417); - buttonRefresh.Name = "buttonRefresh"; - buttonRefresh.Size = new Size(177, 35); - buttonRefresh.TabIndex = 6; - buttonRefresh.Text = "Обновить"; - buttonRefresh.UseVisualStyleBackColor = true; - buttonRefresh.Click += ButtonRefresh_Click; + panelCompanyTools.Controls.Add(buttonAddPlane); + panelCompanyTools.Controls.Add(buttonAddAirPlane); + panelCompanyTools.Controls.Add(maskedTextBox); + panelCompanyTools.Controls.Add(buttonRefresh); + panelCompanyTools.Controls.Add(buttonRemovePlane); + panelCompanyTools.Controls.Add(buttonGoToCheck); + panelCompanyTools.Dock = DockStyle.Bottom; + panelCompanyTools.Enabled = false; + panelCompanyTools.Location = new Point(3, 340); + panelCompanyTools.Name = "panelCompanyTools"; + panelCompanyTools.Size = new Size(189, 215); + panelCompanyTools.TabIndex = 8; // - // buttonGoToCheck + // buttonAddPlane // - buttonGoToCheck.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonGoToCheck.Location = new Point(6, 320); - buttonGoToCheck.Name = "buttonGoToCheck"; - buttonGoToCheck.Size = new Size(177, 35); - buttonGoToCheck.TabIndex = 5; - buttonGoToCheck.Text = "Передать на тесты"; - buttonGoToCheck.UseVisualStyleBackColor = true; - buttonGoToCheck.Click += ButtonGoToCheck_Click; - // - // buttonRemovePlane - // - buttonRemovePlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonRemovePlane.Location = new Point(7, 255); - buttonRemovePlane.Name = "buttonRemovePlane"; - buttonRemovePlane.Size = new Size(177, 35); - buttonRemovePlane.TabIndex = 4; - buttonRemovePlane.Text = "Удалить самолёт"; - buttonRemovePlane.UseVisualStyleBackColor = true; - buttonRemovePlane.Click += ButtonRemovePlane_Click; - // - // maskedTextBox - // - maskedTextBox.Location = new Point(7, 207); - maskedTextBox.Mask = "00"; - maskedTextBox.Name = "maskedTextBox"; - maskedTextBox.Size = new Size(180, 23); - maskedTextBox.TabIndex = 3; - maskedTextBox.ValidatingType = typeof(int); - maskedTextBox.MaskInputRejected += MaskedTextBox_MaskInputRejected; + buttonAddPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonAddPlane.Location = new Point(3, 13); + buttonAddPlane.Name = "buttonAddPlane"; + buttonAddPlane.Size = new Size(166, 28); + buttonAddPlane.TabIndex = 1; + buttonAddPlane.Text = "Добавление самолёта"; + buttonAddPlane.UseVisualStyleBackColor = true; + buttonAddPlane.Click += ButtonAddPlane_Click; // // buttonAddAirPlane // buttonAddAirPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonAddAirPlane.Location = new Point(7, 135); + buttonAddAirPlane.Location = new Point(3, 47); buttonAddAirPlane.Name = "buttonAddAirPlane"; - buttonAddAirPlane.Size = new Size(177, 47); + buttonAddAirPlane.Size = new Size(166, 38); buttonAddAirPlane.TabIndex = 2; buttonAddAirPlane.Text = "Добавление самолёта с радаром"; buttonAddAirPlane.UseVisualStyleBackColor = true; buttonAddAirPlane.Click += ButtonAddAirPlane_Click; // - // buttonAddPlane + // maskedTextBox // - buttonAddPlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; - buttonAddPlane.Location = new Point(6, 80); - buttonAddPlane.Name = "buttonAddPlane"; - buttonAddPlane.Size = new Size(177, 37); - buttonAddPlane.TabIndex = 1; - buttonAddPlane.Text = "Добавление самолёта"; - buttonAddPlane.UseVisualStyleBackColor = true; - buttonAddPlane.Click += ButtonAddPlane_Click; + maskedTextBox.Location = new Point(3, 91); + maskedTextBox.Mask = "00"; + maskedTextBox.Name = "maskedTextBox"; + maskedTextBox.Size = new Size(166, 23); + maskedTextBox.TabIndex = 3; + maskedTextBox.ValidatingType = typeof(int); + maskedTextBox.MaskInputRejected += MaskedTextBox_MaskInputRejected; + // + // buttonRefresh + // + buttonRefresh.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonRefresh.Location = new Point(4, 181); + buttonRefresh.Name = "buttonRefresh"; + buttonRefresh.Size = new Size(166, 25); + buttonRefresh.TabIndex = 6; + buttonRefresh.Text = "Обновить"; + buttonRefresh.UseVisualStyleBackColor = true; + buttonRefresh.Click += ButtonRefresh_Click; + // + // buttonRemovePlane + // + buttonRemovePlane.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonRemovePlane.Location = new Point(3, 120); + buttonRemovePlane.Name = "buttonRemovePlane"; + buttonRemovePlane.Size = new Size(166, 24); + buttonRemovePlane.TabIndex = 4; + buttonRemovePlane.Text = "Удалить самолёт"; + buttonRemovePlane.UseVisualStyleBackColor = true; + buttonRemovePlane.Click += ButtonRemovePlane_Click; + // + // buttonGoToCheck + // + buttonGoToCheck.Anchor = AnchorStyles.Top | AnchorStyles.Left | AnchorStyles.Right; + buttonGoToCheck.Location = new Point(4, 150); + buttonGoToCheck.Name = "buttonGoToCheck"; + buttonGoToCheck.Size = new Size(166, 25); + buttonGoToCheck.TabIndex = 5; + buttonGoToCheck.Text = "Передать на тесты"; + buttonGoToCheck.UseVisualStyleBackColor = true; + buttonGoToCheck.Click += ButtonGoToCheck_Click; + // + // buttonCreateCompany + // + buttonCreateCompany.Location = new Point(6, 314); + buttonCreateCompany.Name = "buttonCreateCompany"; + buttonCreateCompany.Size = new Size(177, 23); + buttonCreateCompany.TabIndex = 7; + buttonCreateCompany.Text = "Создать компанию"; + buttonCreateCompany.UseVisualStyleBackColor = true; + buttonCreateCompany.Click += ButtonCreateCompany_Click; + // + // panelStorage + // + panelStorage.Controls.Add(buttonCollectionDel); + panelStorage.Controls.Add(listBoxCollection); + panelStorage.Controls.Add(buttonCollectionAdd); + panelStorage.Controls.Add(radioButtonList); + panelStorage.Controls.Add(radioButtonMassive); + panelStorage.Controls.Add(textBoxCollectionName); + panelStorage.Controls.Add(labelCollectionName); + panelStorage.Dock = DockStyle.Top; + panelStorage.Location = new Point(3, 19); + panelStorage.Name = "panelStorage"; + panelStorage.Size = new Size(189, 260); + panelStorage.TabIndex = 7; + // + // buttonCollectionDel + // + buttonCollectionDel.Location = new Point(7, 226); + buttonCollectionDel.Name = "buttonCollectionDel"; + buttonCollectionDel.Size = new Size(173, 23); + buttonCollectionDel.TabIndex = 6; + buttonCollectionDel.Text = "Удалить коллекцию"; + buttonCollectionDel.UseVisualStyleBackColor = true; + buttonCollectionDel.Click += ButtonCollectionDel_Click; + // + // listBoxCollection + // + listBoxCollection.FormattingEnabled = true; + listBoxCollection.ItemHeight = 15; + listBoxCollection.Location = new Point(7, 113); + listBoxCollection.Name = "listBoxCollection"; + listBoxCollection.Size = new Size(173, 109); + listBoxCollection.TabIndex = 5; + // + // buttonCollectionAdd + // + buttonCollectionAdd.Location = new Point(7, 81); + buttonCollectionAdd.Name = "buttonCollectionAdd"; + buttonCollectionAdd.Size = new Size(174, 25); + buttonCollectionAdd.TabIndex = 4; + buttonCollectionAdd.Text = "Добавить коллекцию"; + buttonCollectionAdd.UseVisualStyleBackColor = true; + buttonCollectionAdd.Click += ButtonCollectionAdd_Click; + // + // radioButtonList + // + radioButtonList.AutoSize = true; + radioButtonList.Location = new Point(114, 56); + radioButtonList.Name = "radioButtonList"; + radioButtonList.Size = new Size(66, 19); + radioButtonList.TabIndex = 3; + radioButtonList.TabStop = true; + radioButtonList.Text = "Список"; + radioButtonList.UseVisualStyleBackColor = true; + // + // radioButtonMassive + // + radioButtonMassive.AutoSize = true; + radioButtonMassive.Location = new Point(6, 56); + radioButtonMassive.Name = "radioButtonMassive"; + radioButtonMassive.Size = new Size(67, 19); + radioButtonMassive.TabIndex = 2; + radioButtonMassive.TabStop = true; + radioButtonMassive.Text = "Массив"; + radioButtonMassive.UseVisualStyleBackColor = true; + // + // textBoxCollectionName + // + textBoxCollectionName.Location = new Point(3, 27); + textBoxCollectionName.Name = "textBoxCollectionName"; + textBoxCollectionName.Size = new Size(181, 23); + textBoxCollectionName.TabIndex = 1; + // + // labelCollectionName + // + labelCollectionName.AutoSize = true; + labelCollectionName.Location = new Point(40, 9); + labelCollectionName.Name = "labelCollectionName"; + labelCollectionName.Size = new Size(122, 15); + labelCollectionName.TabIndex = 0; + labelCollectionName.Text = "Название коллекции"; // // comboBoxSelectorCompany // @@ -129,7 +245,7 @@ comboBoxSelectorCompany.DropDownStyle = ComboBoxStyle.DropDownList; comboBoxSelectorCompany.FormattingEnabled = true; comboBoxSelectorCompany.Items.AddRange(new object[] { "Хранилище" }); - comboBoxSelectorCompany.Location = new Point(6, 22); + comboBoxSelectorCompany.Location = new Point(6, 285); comboBoxSelectorCompany.Name = "comboBoxSelectorCompany"; comboBoxSelectorCompany.Size = new Size(178, 23); comboBoxSelectorCompany.TabIndex = 0; @@ -140,7 +256,7 @@ pictureBox.Dock = DockStyle.Fill; pictureBox.Location = new Point(0, 0); pictureBox.Name = "pictureBox"; - pictureBox.Size = new Size(686, 513); + pictureBox.Size = new Size(686, 558); pictureBox.TabIndex = 1; pictureBox.TabStop = false; // @@ -148,13 +264,16 @@ // AutoScaleDimensions = new SizeF(7F, 15F); AutoScaleMode = AutoScaleMode.Font; - ClientSize = new Size(881, 513); + ClientSize = new Size(881, 558); Controls.Add(pictureBox); Controls.Add(groupBoxTools); Name = "FormPlaneCollection"; Text = "Коллекция самолётов"; groupBoxTools.ResumeLayout(false); - groupBoxTools.PerformLayout(); + panelCompanyTools.ResumeLayout(false); + panelCompanyTools.PerformLayout(); + panelStorage.ResumeLayout(false); + panelStorage.PerformLayout(); ((System.ComponentModel.ISupportInitialize)pictureBox).EndInit(); ResumeLayout(false); } @@ -170,5 +289,15 @@ private MaskedTextBox maskedTextBox; private Button buttonGoToCheck; private Button buttonRefresh; + private Panel panelStorage; + private Label labelCollectionName; + private TextBox textBoxCollectionName; + private RadioButton radioButtonMassive; + private RadioButton radioButtonList; + private Button buttonCollectionAdd; + private ListBox listBoxCollection; + private Button buttonCollectionDel; + private Button buttonCreateCompany; + private Panel panelCompanyTools; } } \ No newline at end of file diff --git a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs index c6e665a..f82c901 100644 --- a/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs +++ b/ProjectAirPlane/ProjectAirPlane/FormPlaneCollection.cs @@ -17,6 +17,11 @@ namespace ProjectAirPlane; /// public partial class FormPlaneCollection : Form { + /// + /// Хранилише коллекций + /// + private readonly StorageCollection _storageCollection; + /// /// Компания /// @@ -28,6 +33,7 @@ public partial class FormPlaneCollection : Form public FormPlaneCollection() { InitializeComponent(); + _storageCollection = new(); } /// @@ -37,12 +43,7 @@ public partial class FormPlaneCollection : Form /// private void ComboBoxSelectorCompany_SelectedIndexChanged(object sender, EventArgs e) { - switch (comboBoxSelectorCompany.Text) - { - case "Хранилище": - _company = new PlaneSharingService(pictureBox.Width, pictureBox.Height, new MassiveGenericObjects()); - break; - } + panelCompanyTools.Enabled = false; } /// @@ -101,12 +102,12 @@ public partial class FormPlaneCollection : Form return color; } private void ButtonAddPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningPlane)); - - + + private void ButtonAddAirPlane_Click(object sender, EventArgs e) => CreateObject(nameof(DrawningAirPlane)); - + private void MaskedTextBox_MaskInputRejected(object sender, MaskInputRejectedEventArgs e) { @@ -176,5 +177,100 @@ public partial class FormPlaneCollection : Form } pictureBox.Image = _company.Show(); - } + } + + + /// + /// Добавление коллекции + /// + /// + /// + private void ButtonCollectionAdd_Click(object sender, EventArgs e) + { + if (string.IsNullOrEmpty(textBoxCollectionName.Text) || (!radioButtonList.Checked && !radioButtonMassive.Checked)) + { + MessageBox.Show("Не все данные заполнены", "Ошибка", MessageBoxButtons.OK, MessageBoxIcon.Error); + return; + } + + CollectionType collectionType = CollectionType.None; + if (radioButtonMassive.Checked) + { + collectionType = CollectionType.Massive; + } + else if (radioButtonList.Checked) + { + collectionType = CollectionType.List; + } + + _storageCollection.AddCollection(textBoxCollectionName.Text, collectionType); + RerfreshListBoxItems(); + } + + /// + /// Обновление списка в listBoxCollection + /// + private void RerfreshListBoxItems() + { + listBoxCollection.Items.Clear(); + for (int i = 0; i < _storageCollection.Keys?.Count; ++i) + { + string? colName = _storageCollection.Keys?[i]; + if (!string.IsNullOrEmpty(colName)) + { + listBoxCollection.Items.Add(colName); + } + } + + } + /// + /// Удаление коллекции + /// + /// + /// + private void ButtonCollectionDel_Click(object sender, EventArgs e) + { + if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null) + { + MessageBox.Show("Коллекция не выбрана"); + return; + } + if (MessageBox.Show("Удалить коллекцию?", "Удаление", MessageBoxButtons.YesNo, MessageBoxIcon.Question) == DialogResult.No) + { + return; + } + _storageCollection.DelCollection(listBoxCollection.SelectedItem.ToString()); + RerfreshListBoxItems(); + } + /// + /// Создание компании + /// + /// + /// + private void ButtonCreateCompany_Click(object sender, EventArgs e) + { + if (listBoxCollection.SelectedIndex < 0 || listBoxCollection.SelectedItem == null) + { + MessageBox.Show("Коллекция не выбрана"); + return; + } + + ICollectionGenericObjects? collection = _storageCollection[listBoxCollection.SelectedItem.ToString() ?? string.Empty]; + if (collection == null) + { + MessageBox.Show("Коллекция не проинициализирована"); + return; + } + + switch (comboBoxSelectorCompany.Text) + { + case "Хранилище": + _company = new PlaneSharingService(pictureBox.Width, pictureBox.Height, collection); + break; + } + + panelCompanyTools.Enabled = true; + RerfreshListBoxItems(); + } } + -- 2.25.1