diff --git a/.idea/.gitignore b/.idea/.gitignore new file mode 100644 index 0000000..26d3352 --- /dev/null +++ b/.idea/.gitignore @@ -0,0 +1,3 @@ +# Default ignored files +/shelf/ +/workspace.xml diff --git a/.idea/Catamarans.iml b/.idea/Catamarans.iml new file mode 100644 index 0000000..b107a2d --- /dev/null +++ b/.idea/Catamarans.iml @@ -0,0 +1,11 @@ + + + + + + + + + + + \ No newline at end of file diff --git a/.idea/misc.xml b/.idea/misc.xml new file mode 100644 index 0000000..07115cd --- /dev/null +++ b/.idea/misc.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/.idea/modules.xml b/.idea/modules.xml new file mode 100644 index 0000000..f9b8061 --- /dev/null +++ b/.idea/modules.xml @@ -0,0 +1,8 @@ + + + + + + + + \ No newline at end of file diff --git a/.idea/vcs.xml b/.idea/vcs.xml new file mode 100644 index 0000000..35eb1dd --- /dev/null +++ b/.idea/vcs.xml @@ -0,0 +1,6 @@ + + + + + + \ No newline at end of file diff --git a/Resources/30px_arrow_down.png b/Resources/30px_arrow_down.png new file mode 100644 index 0000000..7aa3255 Binary files /dev/null and b/Resources/30px_arrow_down.png differ diff --git a/Resources/30px_arrow_left.png b/Resources/30px_arrow_left.png new file mode 100644 index 0000000..9a3dfa2 Binary files /dev/null and b/Resources/30px_arrow_left.png differ diff --git a/Resources/30px_arrow_right.png b/Resources/30px_arrow_right.png new file mode 100644 index 0000000..0f06fd0 Binary files /dev/null and b/Resources/30px_arrow_right.png differ diff --git a/Resources/30px_arrow_up.png b/Resources/30px_arrow_up.png new file mode 100644 index 0000000..67ae4bc Binary files /dev/null and b/Resources/30px_arrow_up.png differ diff --git a/src/DrawingBoat.java b/src/DrawingBoat.java new file mode 100644 index 0000000..447fd76 --- /dev/null +++ b/src/DrawingBoat.java @@ -0,0 +1,199 @@ +package src; + +import java.awt.*; +import java.util.Random; + +public class DrawingBoat { + // Объект-сущность лодки + 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) { + 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; + } + } + + // Метод перемешения обхекта + public void MoveTransport(EnumDirection enumDirection) { + // Если не установлен объект-сущность - выходим + if (entityBoat == null) { + return; + } + + // Если не назначены границы области отрисовки - выходим + if (__pictureWidth == null || __pictureHeight == null) { + return; + } + + // Проверяем возможность перемещения и перемещаем обхект по заданному направлению + switch (enumDirection) { + case Right: + if (__startPosX + __boatWidth + entityBoat.Step() < __pictureWidth) { + __startPosX += entityBoat.Step(); + } + break; + case Left: + if (__startPosX - entityBoat.Step() > 0) { + __startPosX -= entityBoat.Step(); + } + break; + case Up: + if (__startPosY - entityBoat.Step() > 0) { + __startPosY -= entityBoat.Step(); + } + break; + case Down: + if (__startPosY + __boatHeight + entityBoat.Step() < __pictureHeight) { + __startPosY += entityBoat.Step(); + } + break; + } + } + + // Метод отрисовки объекта + public void DrawTransport(Graphics g) { + // Если не установлен объект-сущность - выходим + if (entityBoat == null) { + return; + } + + // Если координаты не валидны или размер области отрисовки не установлен - выходим + 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 = null; + __pictureHeight = null; + return; + } + + // Если выходим за правую границу, то сдвигаемся влево + if (__startPosX + __boatWidth > __pictureWidth) { + __startPosX = __pictureWidth - __boatWidth; + } + + // Если выходим за нижнюю границу, то сдвигаемся вверх + 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 new file mode 100644 index 0000000..77152e8 --- /dev/null +++ b/src/EntityBoat.java @@ -0,0 +1,25 @@ +package src; + +import java.awt.*; +import java.util.Random; + +public class EntityBoat { + // Скорость лодки + public int Speed; + // Вес лодки + public float Weight; + // Цвет корпуса + public Color BodyColor; + + // Шаг перемещения + public float Step() { + return Speed * 100 / Weight; + } + + public void Init(int speed, float weight, Color bodyColor) { + Random rnd = new Random(); + Speed = speed <= 0 ? rnd.nextInt(50, 150) : speed; + Weight = weight <= 0 ? rnd.nextInt(40, 70) : weight; + BodyColor = bodyColor; + } +} 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 new file mode 100644 index 0000000..ef5a2d4 --- /dev/null +++ b/src/FormBoat.form @@ -0,0 +1,134 @@ + +
+ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + +
diff --git a/src/FormBoat.java b/src/FormBoat.java new file mode 100644 index 0000000..1ee812e --- /dev/null +++ b/src/FormBoat.java @@ -0,0 +1,153 @@ +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; + private JLabel StatusStripLabelSpeed; + private JLabel StatusStripLabelWeight; + private JLabel StatusStripLabelColor; + private JButton ButtonCreate; + 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); + } +} diff --git a/src/Program.java b/src/Program.java new file mode 100644 index 0000000..d8d19a6 --- /dev/null +++ b/src/Program.java @@ -0,0 +1,16 @@ +package src; + +import javax.swing.*; + +public class Program { + public static void main(String[] args) { + JFrame.setDefaultLookAndFeelDecorated(false); + JFrame frame = new JFrame("Катамаран"); + frame.setContentPane(new FormBoat().PanelWrapper); + frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE); + frame.setLocation(500, 200); + frame.pack(); + frame.setSize(1000, 500); + frame.setVisible(true); + } +}