diff --git a/src/Direction.java b/src/Direction.java deleted file mode 100644 index 5391974..0000000 --- a/src/Direction.java +++ /dev/null @@ -1,8 +0,0 @@ -package src; - -public enum Direction { - Up, - Down, - Left, - Right -} diff --git a/src/DrawingBoat.java b/src/DrawingBoat.java index 1e59761..447fd76 100644 --- a/src/DrawingBoat.java +++ b/src/DrawingBoat.java @@ -1,100 +1,199 @@ package src; import java.awt.*; +import java.util.Random; public class DrawingBoat { - public EntityBoat Boat; - private float _startPosX; - private float _startPosY; - private int _pictureWidth = 0; - private int _pictureHeight = 0; - private final int _boatWidth = 100; - private final int _boatHeight = 40; + // Объект-сущность лодки + public EntityBoat entityBoat; + // Объект отрисовки весел лодки + private DrawingBoatPaddle __drawingBoatPaddle; + // Координата X верхнего левого угла лодки + private float __startPosX; + // Координата Y верхнего левого угла лодки + private float __startPosY; + // Ширина отрисовки лодки + private final int __boatWidth = 100; + // Высота отрисовки лодки + private final int __boatHeight = 60; + // Ширина области отрисовки + private Integer __pictureWidth = null; + // Высота области отрисовки + private Integer __pictureHeight = null; + + // Инициализатор класса public void Init(int speed, float weight, Color bodyColor) { - Boat = new EntityBoat(); - Boat.Init(speed, weight, bodyColor); + entityBoat = new EntityBoat(); + entityBoat.Init(speed, weight, bodyColor); + __drawingBoatPaddle = new DrawingBoatPaddle(); + SetPaddlesCount(); } + // Метод для установки количества весел лодки + public void SetPaddlesCount() { + Random rnd = new Random(); + int paddlesCount = rnd.nextInt(1, 4); + __drawingBoatPaddle.SetEnumNumber(paddlesCount); + } + + // Метод установки позиции и размеров объекта public void SetPosition(int x, int y, int width, int height) { - if (x > 0 && x < width - _boatWidth && y > 0 && y < height - _boatHeight) { - _startPosX = x; - _startPosY = y; - _pictureWidth = width; - _pictureHeight = height; + if (x > 0 && x < width - __boatWidth && y > 0 && y < height - __boatHeight) { + __startPosX = x; + __startPosY = y; + __pictureWidth = width; + __pictureHeight = height; } } - public void MoveTransport(Direction direction) { - if (_pictureWidth == 0 || _pictureHeight == 0) { + // Метод перемешения обхекта + public void MoveTransport(EnumDirection enumDirection) { + // Если не установлен объект-сущность - выходим + if (entityBoat == null) { return; } - switch (direction) { + + // Если не назначены границы области отрисовки - выходим + if (__pictureWidth == null || __pictureHeight == null) { + return; + } + + // Проверяем возможность перемещения и перемещаем обхект по заданному направлению + switch (enumDirection) { case Right: - if (_startPosX + _boatWidth + Boat.Step < _pictureWidth) { - _startPosX += Boat.Step; + if (__startPosX + __boatWidth + entityBoat.Step() < __pictureWidth) { + __startPosX += entityBoat.Step(); } break; case Left: - if (_startPosX - Boat.Step > 0) { - _startPosX -= Boat.Step; + if (__startPosX - entityBoat.Step() > 0) { + __startPosX -= entityBoat.Step(); } break; case Up: - if (_startPosY - Boat.Step > 0) { - _startPosY -= Boat.Step; + if (__startPosY - entityBoat.Step() > 0) { + __startPosY -= entityBoat.Step(); } break; case Down: - if (_startPosY + _boatHeight + Boat.Step < _pictureHeight) { - _startPosY += Boat.Step; + if (__startPosY + __boatHeight + entityBoat.Step() < __pictureHeight) { + __startPosY += entityBoat.Step(); } break; } } - public void DrawTransport(Graphics g) - { - if (_startPosX < 0 || _startPosY < 0 - || _pictureHeight == 0 || _pictureWidth == 0) - { + // Метод отрисовки объекта + public void DrawTransport(Graphics g) { + // Если не установлен объект-сущность - выходим + if (entityBoat == null) { return; } -// todo доделать прорисовку -// SolidBrush brush = new SolidBrush(Boat.BodyColor); -// -// PointF[] bodyPoints = new PointF[5]; -// bodyPoints[0] = new PointF(_startPosX, _startPosY); -// bodyPoints[1] = new PointF(_startPosX + _boatWidth - _boatWidth / 4, _startPosY); -// bodyPoints[2] = new PointF(_startPosX + _boatWidth, _startPosY + _boatHeight / 2); -// bodyPoints[3] = new PointF(_startPosX + _boatWidth - _boatWidth / 4, _startPosY + _boatHeight); -// bodyPoints[4] = new PointF(_startPosX, _startPosY + _boatHeight); -// -// // Отрисовка корпуса лодки -// g.FillPolygon(brush, bodyPoints); -// g.DrawPolygon(Pens.Black, bodyPoints); -// -// // Отрисовка головы лодки -// g.FillEllipse(Brushes.White, _startPosX + _boatWidth / 8, _startPosY + _boatHeight / 8, -// _boatWidth / 2, _boatHeight - _boatHeight / 4); -// g.DrawEllipse(Pens.Black, _startPosX + _boatWidth / 8, _startPosY + _boatHeight / 8, -// _boatWidth / 2, _boatHeight - _boatHeight / 4); + // Если координаты не валидны или размер области отрисовки не установлен - выходим + if (__startPosX < 0 || __startPosY < 0 + || __pictureHeight == null || __pictureWidth == null) { + return; + } + + Graphics2D g2d = (Graphics2D) g; + + int height = __boatHeight - 30; + + // Промежуточные переменные, чтобы не писать каждый раз (int) + int startX = (int) __startPosX; + int startY = (int) __startPosY + 15; + + // Рисуем корпус лодки + // Задаем цвет корпуса + g2d.setColor(entityBoat.BodyColor); + + // Массив координат X для полигона корпуса лодки + int[] xPoints = new int[]{ + startX, + startX + __boatWidth - __boatWidth / 4, + startX + __boatWidth, + startX + __boatWidth - __boatWidth / 4, + startX + }; + + // Массив координат Y для полигона корпуса лодки + int[] yPoints = new int[]{ + startY, + startY, + startY + height / 2, + startY + height, + startY + height + }; + + // Заполняем полигон + g2d.fillPolygon(xPoints, yPoints, 5); + + // Рисуем окантовку + g2d.setColor(Color.BLACK); + g2d.drawPolygon(xPoints, yPoints, 5); + + // Рисуем палубу + // Левая дуга + g2d.drawArc( + startX + __boatWidth / 10, + startY + height / 5, + height - height / 5 - height / 5, + height - height / 5 - height / 5, + 90, 180 + ); + + // Правая дуга + g2d.drawArc( + startX + __boatWidth - __boatWidth / 4 - __boatWidth / 10 - height / 5, + startY + height / 5, + height - height / 5 - height / 5, + height - height / 5 - height / 5, + -90, 180 + ); + + // Верхняя линия + g2d.drawLine( + startX + __boatWidth / 10 + (height - height / 2) / 2, + startY + height / 5, + startX + __boatWidth - __boatWidth / 4 - __boatWidth / 10 - height / 5 + (height - height / 2) / 2, + startY + height / 5 + ); + + // Нижняя линия + g2d.drawLine( + startX + __boatWidth / 10 + (height - height / 2) / 2, + startY + height - height / 5, + startX + __boatWidth - __boatWidth / 4 - __boatWidth / 10 - height / 5 + (height - height / 2) / 2, + startY + height - height / 5 + ); + + // Отрисовка весел лодки + __drawingBoatPaddle.DrawBoatPaddles(g, entityBoat.BodyColor, __startPosX, startY, __boatWidth, height); } + // Метод изменения границ области отрисовки public void ChangeBorders(int width, int height) { - _pictureWidth = width; - _pictureHeight = height; - if (_pictureWidth <= _boatWidth || _pictureHeight <= _boatHeight) { - _pictureWidth = 0; - _pictureHeight = 0; + __pictureWidth = width; + __pictureHeight = height; + + // Если новые размеры области отрисовки меньше, чем размеры отрисовки лодки, + // то обнуляем размеры области отрисовки - рисовать не можем + if (__pictureWidth <= __boatWidth || __pictureHeight <= __boatHeight) { + __pictureWidth = null; + __pictureHeight = null; return; } - if (_startPosX + _boatWidth > _pictureWidth) { - _startPosX = _pictureWidth - _boatWidth; + + // Если выходим за правую границу, то сдвигаемся влево + if (__startPosX + __boatWidth > __pictureWidth) { + __startPosX = __pictureWidth - __boatWidth; } - if (_startPosY + _boatHeight > _pictureHeight) { - _startPosY = _pictureHeight - _boatHeight; + + // Если выходим за нижнюю границу, то сдвигаемся вверх + if (__startPosY + __boatHeight > __pictureHeight) { + __startPosY = __pictureHeight - __boatHeight; } } } diff --git a/src/DrawingBoatPaddle.java b/src/DrawingBoatPaddle.java new file mode 100644 index 0000000..a5f2fe8 --- /dev/null +++ b/src/DrawingBoatPaddle.java @@ -0,0 +1,49 @@ +package src; + +import java.awt.*; + +public class DrawingBoatPaddle { + private EnumPaddlesCount __enumPaddlesCount; + private final BasicStroke __paddleStroke = new BasicStroke(3); + + public void SetEnumNumber(int paddlesCount) { + for (EnumPaddlesCount val : __enumPaddlesCount.values()) { + if (val.enumNumber == paddlesCount) { + __enumPaddlesCount = val; + return; + } + } + } + + public void DrawBoatPaddles(Graphics g, Color color, + float startPosX, float startPosY, int boatWidth, int boatHeight) { + int startX = (int) startPosX; + int startY = (int) startPosY; + + Graphics2D g2d = (Graphics2D) g; + // Задаем цвет как у лодки + g2d.setColor(color); + // Задаем толщину линии побольше + g2d.setStroke(__paddleStroke); + + // Промежуточная переменная, чтобы уменьшить расчеты + float t = boatWidth - (float) boatWidth / 4 - (float) boatWidth / 15; + + for (int i = 0; i < __enumPaddlesCount.enumNumber; i++) { + // Рисуем верхнее весло + g2d.drawLine( + (int) (startX + t - t / 3 * i), + startY, + (int) (startX + t - t / 3 * (i + 1)), + startY - 15 + ); + // Рисуем нижнее весло + g2d.drawLine( + (int) (startX + t - t / 3 * i), + startY + boatHeight, + (int) (startX + t - t / 3 * (i + 1)), + startY + boatHeight + 15 + ); + } + } +} diff --git a/src/EntityBoat.java b/src/EntityBoat.java index 899cf03..77152e8 100644 --- a/src/EntityBoat.java +++ b/src/EntityBoat.java @@ -4,10 +4,17 @@ import java.awt.*; import java.util.Random; public class EntityBoat { + // Скорость лодки public int Speed; + // Вес лодки public float Weight; + // Цвет корпуса public Color BodyColor; - public float Step; + + // Шаг перемещения + public float Step() { + return Speed * 100 / Weight; + } public void Init(int speed, float weight, Color bodyColor) { Random rnd = new Random(); diff --git a/src/EnumDirection.java b/src/EnumDirection.java new file mode 100644 index 0000000..45e77ea --- /dev/null +++ b/src/EnumDirection.java @@ -0,0 +1,9 @@ +package src; + +// Перечисление для направлений движения лодки +public enum EnumDirection { + Up, + Down, + Left, + Right +} diff --git a/src/EnumPaddlesCount.java b/src/EnumPaddlesCount.java new file mode 100644 index 0000000..a5da9e6 --- /dev/null +++ b/src/EnumPaddlesCount.java @@ -0,0 +1,14 @@ +package src; + +// Дополнительное перечисление количества весел +public enum EnumPaddlesCount { + One(1), + Two(2), + Three(3); + + public final int enumNumber; + + EnumPaddlesCount(int i) { + this.enumNumber = i; + } +} diff --git a/src/FormBoat.form b/src/FormBoat.form index 7dd7ac3..ef5a2d4 100644 --- a/src/FormBoat.form +++ b/src/FormBoat.form @@ -8,93 +8,29 @@ - + - + + + - + - + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + @@ -103,6 +39,62 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/src/FormBoat.java b/src/FormBoat.java index 7e4b68a..1ee812e 100644 --- a/src/FormBoat.java +++ b/src/FormBoat.java @@ -1,8 +1,18 @@ package src; import javax.swing.*; +import java.awt.*; +import java.awt.event.ComponentAdapter; +import java.awt.event.ComponentEvent; +import java.util.LinkedList; +import java.util.List; +import java.util.Random; +import java.awt.event.ActionEvent; +import java.awt.event.ActionListener; public class FormBoat { + protected DrawingBoat _drawingBoat = new DrawingBoat(); + JPanel PanelWrapper; private JPanel PictureBox; private JToolBar StatusStrip; @@ -10,9 +20,134 @@ public class FormBoat { private JLabel StatusStripLabelWeight; private JLabel StatusStripLabelColor; private JButton ButtonCreate; - private JPanel PanelButtonsMove; private JButton ButtonDown; private JButton ButtonUp; private JButton ButtonLeft; private JButton ButtonRight; + + private List __controls; + + // Конструктор формы + public FormBoat() { + // Инициализируем список элементов управления для их перерисовки + InitializeControlsRepaintList(); + + ButtonUp.setName("ButtonUp"); + ButtonDown.setName("ButtonDown"); + ButtonLeft.setName("ButtonLeft"); + ButtonRight.setName("ButtonRight"); + + // Обработчик нажатия кнопки "Создать" + ButtonCreate.addActionListener(new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Создаем новый объект отрисовки лодки + _drawingBoat = new DrawingBoat(); + Random random = new Random(); + + // Инициализируем обхект отрисовки + _drawingBoat.Init(random.nextInt(100, 300), random.nextInt(1000, 2000), + new Color(random.nextInt(256), random.nextInt(256), random.nextInt(256))); + + // Устанавливаем позицию и размеры объекта отрисовки + _drawingBoat.SetPosition(random.nextInt(10, 100), random.nextInt(10, 100), + PictureBox.getWidth(), PictureBox.getHeight()); + + // Обновляем информацию в статусбаре + StatusStripLabelSpeed.setText("Скорость: " + _drawingBoat.entityBoat.Speed + " "); + StatusStripLabelWeight.setText("Вес: " + _drawingBoat.entityBoat.Weight + " "); + Color color = _drawingBoat.entityBoat.BodyColor; + StatusStripLabelColor.setText("Цвет: (" + color.getRed() + ", " + color.getGreen() + ", " + color.getBlue() + ")"); + + // Перерисовываем содержимое + Draw(); + } + }); + + // Обработчик изменения размеров формы + PanelWrapper.addComponentListener(new ComponentAdapter() { + @Override + public void componentResized(ComponentEvent e) { + super.componentResized(e); + + // Изменяем граници области отрисовки для объекта отрисовки + _drawingBoat.ChangeBorders(PictureBox.getWidth(), PictureBox.getHeight()); + + // Перерисовываем содержимое + Draw(); + } + }); + + ActionListener buttonMoveClickedListener = new ActionListener() { + @Override + public void actionPerformed(ActionEvent e) { + // Получаем имя кнопки перемещения + String buttonName = ((JButton) e.getSource()).getName(); + + // В зависимости от нажатой кнопки перемещаяем объект + switch (buttonName) { + case ("ButtonUp"): { + _drawingBoat.MoveTransport(EnumDirection.Up); + } + break; + case ("ButtonDown"): { + _drawingBoat.MoveTransport(EnumDirection.Down); + } + break; + case ("ButtonLeft"): { + _drawingBoat.MoveTransport(EnumDirection.Left); + } + break; + case ("ButtonRight"): { + _drawingBoat.MoveTransport(EnumDirection.Right); + } + break; + } + + // Перерисовываем содержимое + Draw(); + } + }; + + ButtonUp.addActionListener(buttonMoveClickedListener); + ButtonDown.addActionListener(buttonMoveClickedListener); + ButtonLeft.addActionListener(buttonMoveClickedListener); + ButtonRight.addActionListener(buttonMoveClickedListener); + } + + // Метод отрисовки + public void Draw() { + // Если сущности внутри объекта отрисовки нет - выходим + if (_drawingBoat.entityBoat == null) { + return; + } + + // Закрашиваем PictureBox цветом окна (очищаем его) + Graphics g = PictureBox.getGraphics(); + g.setColor(PictureBox.getBackground()); + g.fillRect(0, 0, PictureBox.getWidth(), PictureBox.getHeight()); + + // Рисуем объект + _drawingBoat.DrawTransport(g); + + // Перерисовываем элементы управления (PictureBox закрашивает их) + RepaintControls(); + } + + // Метод перерисовки элементов управления + private void RepaintControls() { + for (JComponent control : __controls) { + control.repaint(); + } + } + + // Метод инициализации списка элементов управления для их перерисовки + private void InitializeControlsRepaintList() { + __controls = new LinkedList<>(); + __controls.add(ButtonCreate); + __controls.add(ButtonUp); + __controls.add(ButtonDown); + __controls.add(ButtonLeft); + __controls.add(ButtonRight); + } }