diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/DrawningAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/DrawningAirFighter.java deleted file mode 100644 index 2ce3663..0000000 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/DrawningAirFighter.java +++ /dev/null @@ -1,171 +0,0 @@ -package com.projectairfighter; - -import javafx.scene.canvas.GraphicsContext; -import javafx.scene.paint.Color; - -import java.util.Random; - -public class DrawningAirFighter { - // Сущность - public EntityAirFighter entityAirFighter; - - private EngineDrawing engineDrawing; - - // Ширина и высота окна - private int pictureWidth = 0; - private int pictureHeight = 0; - - // Начальные координаты прорисовки истребителя - private Double startPosX = null; - private Double startPosY = null; - - private final int drawningAirFighterWidth = 157; - private final int drawningAirFighterHeight = 140; - - - // Инициализация - public void init(int speed, double weight, Color bodyColor, Color additionalColor, - boolean bodyRockets, boolean additionalWings) { - Random random = new Random(); - engineDrawing = new EngineDrawing(); - entityAirFighter = new EntityAirFighter(); - entityAirFighter.init(speed, weight, bodyColor, additionalColor, - bodyRockets, additionalWings); - engineDrawing.setCountEngines(random.nextInt(7)); - } - - - // Установка размеров окна - public void setPictureSize(int width, int height) { - if (width <= drawningAirFighterWidth || height <= drawningAirFighterHeight) return; - pictureWidth = width; - pictureHeight = height; - if (startPosX != null && startPosY != null) { - if (startPosX + drawningAirFighterWidth > pictureWidth) { - startPosX = (double) (pictureWidth - drawningAirFighterWidth); - } - if (startPosY + drawningAirFighterHeight > pictureHeight) { - startPosY = (double) (pictureHeight - drawningAirFighterHeight); - } - } - } - - // Установка позиции - public void setPosition(double x, double y) { - if (pictureWidth == 0 || pictureHeight == 0) { - return; - } - - startPosX = x; - startPosY = y; - - if (y + drawningAirFighterHeight > pictureHeight || y < 0) { - startPosY = (double) 0; - } - if (x + drawningAirFighterWidth > pictureWidth || x < 0) { - startPosX = (double) 0; - } - } - - // Изменение направления перемещения - public boolean moveTransport(DirectionType direction) { - if (entityAirFighter == null || startPosX == -1 || startPosY == -1) { - return false; - } - return switch (direction) { - case LEFT -> { - if (startPosX - entityAirFighter.getStep() > 0) { - startPosX -= entityAirFighter.getStep(); - } - yield true; - } - case UP -> { - if (startPosY - entityAirFighter.getStep() > 0) { - startPosY -= entityAirFighter.getStep(); - } - yield true; - } - case RIGHT -> { - if (startPosX + drawningAirFighterWidth + entityAirFighter.getStep() < pictureWidth) { - startPosX += entityAirFighter.getStep(); - } - yield true; - } - case DOWN -> { - if (startPosY + drawningAirFighterHeight + entityAirFighter.getStep() < pictureHeight) { - startPosY += entityAirFighter.getStep(); - } - yield true; - } - default -> false; - }; - } - - // Прорисовка объекта - public void drawTransport(GraphicsContext gc) { - if (entityAirFighter == null || startPosX == null || startPosY == null) { - return; - } - - if (pictureWidth == 0 || pictureHeight == 0) return; - - gc.setFill(entityAirFighter.getBodyColor()); - gc.setStroke(entityAirFighter.getBodyColor()); - - // Прорисовка тела истребителя - gc.strokeRect(startPosX + 10, startPosY + 53, 130, 26); - - // Прорисовка носа - gc.fillPolygon( - new double[]{startPosX + 140, startPosX + 165, startPosX + 140}, - new double[]{startPosY + 53, startPosY + 66, startPosY + 79}, - 3 - ); - - // Прорисовка верхней части хвоста - gc.strokePolygon(new double[]{startPosX + 10, startPosX + 10, startPosX + 30, startPosX + 30}, - new double[]{startPosY + 23, startPosY + 53, startPosY + 53, startPosY + 38}, 4); - - // Прорисовка нижней части хвоста - gc.strokePolygon(new double[]{startPosX + 10, startPosX + 10, startPosX + 30, startPosX + 30}, - new double[]{startPosY + 79, startPosY + 109, startPosY + 94, startPosY + 79}, 4); - - // Прорисовка верхнего крыла - gc.strokePolygon(new double[]{startPosX + 100, startPosX + 100, startPosX + 70, startPosX + 85}, - new double[]{startPosY, startPosY + 53, startPosY + 53, startPosY}, 4); - - // Прорисовка нижнего крыла - gc.strokePolygon(new double[]{startPosX + 100, startPosX + 100, startPosX + 85, startPosX + 70}, - new double[]{startPosY + 79, startPosY + 133, startPosY + 133, startPosY + 79}, 4); - - engineDrawing.drawEngine(gc, entityAirFighter, startPosX, startPosY); - - // Дополнительные элементы объекта - - if (entityAirFighter.hasBodyRockets()) { - gc.setFill(entityAirFighter.getAdditionalColor()); - gc.setStroke(entityAirFighter.getAdditionalColor()); - - double rocketWidth = 6; - double rocketLength = 15; - - double[] rocketsX = {startPosX + 100, startPosX + 100}; - - for (double rocketPos : rocketsX) { - gc.fillRect(rocketPos, startPosY + 13 - (rocketWidth / 2), rocketLength, rocketWidth); - gc.fillRect(rocketPos, startPosY + 120 - (rocketWidth / 2), rocketLength, rocketWidth); - } - } - - if (entityAirFighter.hasAdditionalWings()) { - gc.setStroke(entityAirFighter.getAdditionalColor()); - double[] additionalWingTopX = {startPosX + 40, startPosX + 50, startPosX + 60}; - double[] additionalWingTopY = {startPosY + 53, startPosY + 38, startPosY + 53}; - double[] additionalWingBottomX = {startPosX + 40, startPosX + 50, startPosX + 60}; - double[] additionalWingBottomY = {startPosY + 80, startPosY + 95, startPosY + 80}; - - gc.strokePolygon(additionalWingTopX, additionalWingTopY, 3); - gc.strokePolygon(additionalWingBottomX, additionalWingBottomY, 3); - } - } -} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/EntityAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/EntityAirFighter.java deleted file mode 100644 index 004a43b..0000000 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/EntityAirFighter.java +++ /dev/null @@ -1,51 +0,0 @@ -package com.projectairfighter; - -import javafx.scene.paint.Color; - -// Перечисление для количества двигателей - -public class EntityAirFighter { - // Скорость - private int speed; - // Вес - private double weight; - // Основной цвет - private Color bodyColor; - // Дополнительный цвет (для опциональных элементов) - private Color additionalColor; - // Признак (опция) наличия ракет - private boolean bodyRockets; - // Признак (опция) наличия дополнительных крыльев - private boolean additionalWings; - // Метод для вычисления шага перемещения истребителя - public double getStep() { - return speed * 100 / weight; - } - - // Конструктор - public void init(int speed, double weight, Color bodyColor, Color additionalColor, - boolean bodyRockets, boolean additionalWings) { - this.speed = speed; - this.weight = weight; - this.bodyColor = bodyColor; - this.additionalColor = additionalColor; - this.bodyRockets = bodyRockets; - this.additionalWings = additionalWings; - } - - public Color getBodyColor() { - return bodyColor; - } - - public Color getAdditionalColor() { - return additionalColor; - } - - public boolean hasBodyRockets() { - return bodyRockets; - } - - public boolean hasAdditionalWings() { - return additionalWings; - } -} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/FormAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/FormAirFighter.java index 0dfd634..13c5d18 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/FormAirFighter.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/FormAirFighter.java @@ -1,5 +1,9 @@ package com.projectairfighter; +import com.projectairfighter.drawnings.DirectionType; +import com.projectairfighter.drawnings.DrawningAirFighter; +import com.projectairfighter.drawnings.DrawningWarPlane; +import com.projectairfighter.movementstrategy.*; import javafx.application.Application; import javafx.event.ActionEvent; import javafx.fxml.FXML; @@ -9,6 +13,7 @@ import javafx.scene.Scene; import javafx.scene.canvas.Canvas; import javafx.scene.canvas.GraphicsContext; import javafx.scene.control.Button; +import javafx.scene.control.ComboBox; import javafx.scene.input.KeyEvent; import javafx.scene.paint.Color; import javafx.stage.Stage; @@ -17,47 +22,95 @@ import java.io.IOException; import java.util.Random; public class FormAirFighter extends Application { - private DrawningAirFighter drawningAirFighter; + private AbstractStrategy strategy; + private DrawningWarPlane drawningWarPlane; // Окно отрисовки @FXML private Canvas canvasAirFighter; + @FXML + private ComboBox comboBoxStrategy; + + @FXML + private void ButtonStrategy_click(){ + if (drawningWarPlane == null) + return; + if (!comboBoxStrategy.isDisabled()) { + int selectedIndex = comboBoxStrategy.getSelectionModel().getSelectedIndex(); + switch (selectedIndex) { + case 0: + strategy = new MoveToCenter(); + break; + case 1: + strategy = new MoveToBorder(); + break; + default: + strategy = null; + break; + } + if (strategy == null) + return; + strategy.setData(new MoveableFighter(drawningWarPlane), (int) canvasAirFighter.getWidth(), (int) canvasAirFighter.getHeight()); + } + if (strategy == null) + return; + comboBoxStrategy.setDisable(true); + strategy.makeStep(); + Draw(); + if (strategy.getStatus() == StrategyStatus.Finish){ + comboBoxStrategy.setDisable(false); + strategy = null; + } + } + + private void createPlane(Random random){ + drawningWarPlane.setPictureSize((int)canvasAirFighter.getWidth(), (int)canvasAirFighter.getHeight()); + drawningWarPlane.setPosition(random.nextInt(100) + 10, random.nextInt(100) + 10); + Scene scene = canvasAirFighter.getScene(); + scene.widthProperty().addListener((observable, oldValue, newValue) -> resizeCanvas()); + scene.heightProperty().addListener((observable, oldValue, newValue) -> resizeCanvas()); + strategy = null; + comboBoxStrategy.setDisable(false); + Draw(); + } + // Создание объекта @FXML private void createAirFighter(ActionEvent event) { Random random = new Random(); - drawningAirFighter = new DrawningAirFighter(); - drawningAirFighter.init(random.nextInt(300) + 100, random.nextInt(3000) + 1000, + drawningWarPlane = new DrawningAirFighter(random.nextInt(100) + 100, random.nextInt(2000) + 1000, Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256)), Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256)), random.nextBoolean(), random.nextBoolean()); + createPlane(random); + } - drawningAirFighter.setPictureSize((int) canvasAirFighter.getWidth(), (int) canvasAirFighter.getHeight()); - drawningAirFighter.setPosition(random.nextInt(100) + 10, random.nextInt(100) + 10); - Scene scene = canvasAirFighter.getScene(); - scene.widthProperty().addListener((observable, oldValue, newValue) -> resizeCanvas()); - scene.heightProperty().addListener((observable, oldValue, newValue) -> resizeCanvas()); - Draw(); + @FXML + private void createWarPlane(ActionEvent event) { + Random random = new Random(); + drawningWarPlane = new DrawningWarPlane(random.nextInt(100) + 100, random.nextInt(2000) + 1000, + Color.rgb(random.nextInt(256), random.nextInt(256), random.nextInt(256))); + createPlane(random); } // Нажатие кнопок двжиения мышкой @FXML private void moveAirFighterByMouse(ActionEvent event) { - if (drawningAirFighter == null) return; + if (drawningWarPlane == null) return; Button btn = (Button) event.getSource(); DirectionType direction = DirectionType.valueOf(btn.getId().toUpperCase()); - boolean result = drawningAirFighter.moveTransport(direction); + boolean result = drawningWarPlane.moveTransport(direction); if (result) Draw(); } // Нажатие кнопок двжиения клавиатурой @FXML private void moveAirFighterByKey(KeyEvent event){ - if (drawningAirFighter == null) return; + if (drawningWarPlane == null) return; Button btn = (Button) event.getSource(); DirectionType direction = DirectionType.valueOf(btn.getId().toUpperCase()); - boolean result = drawningAirFighter.moveTransport(direction); + boolean result = drawningWarPlane.moveTransport(direction); if (result) Draw(); } @@ -66,15 +119,15 @@ public class FormAirFighter extends Application { private void resizeCanvas() { canvasAirFighter.setWidth(canvasAirFighter.getScene().getWidth()); canvasAirFighter.setHeight(canvasAirFighter.getScene().getHeight()); - drawningAirFighter.setPictureSize((int) canvasAirFighter.getWidth(), (int) canvasAirFighter.getHeight()); + drawningWarPlane.setPictureSize((int) canvasAirFighter.getWidth(), (int) canvasAirFighter.getHeight()); } // Функция отрисовки объекта private void Draw() { - if (drawningAirFighter == null) return; + if (drawningWarPlane == null) return; GraphicsContext gc = canvasAirFighter.getGraphicsContext2D(); gc.clearRect(0, 0, canvasAirFighter.getWidth(), canvasAirFighter.getHeight()); - drawningAirFighter.drawTransport(gc); + drawningWarPlane.drawTransport(gc); } @FXML @@ -84,6 +137,9 @@ public class FormAirFighter extends Application { loader.setLocation(FormAirFighter.class.getResource("Form.fxml")); Parent root = loader.load(); canvasAirFighter = (Canvas) loader.getNamespace().get("canvasAirFighter"); + comboBoxStrategy = (ComboBox) loader.getNamespace().get("comboBoxStrategy"); + comboBoxStrategy.getItems().addAll("К центру", "К краю"); + strategy = null; Scene scene = new Scene(root, 800, 400); primaryStage.setTitle("Истребитель"); diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/DirectionType.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DirectionType.java similarity index 72% rename from ProjectAirFighter/src/main/java/com/projectairfighter/DirectionType.java rename to ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DirectionType.java index 4dbffc0..32f3f1e 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/DirectionType.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DirectionType.java @@ -1,6 +1,7 @@ -package com.projectairfighter; +package com.projectairfighter.drawnings; public enum DirectionType { + UNKNOWN, // Вверх UP, // Вниз diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawableExtras.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawableExtras.java new file mode 100644 index 0000000..e41f913 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawableExtras.java @@ -0,0 +1,9 @@ +package com.projectairfighter.drawnings; + +import com.projectairfighter.entities.EntityAirFighter; +import javafx.scene.canvas.GraphicsContext; + +public interface DrawableExtras { + void setCountEngines(int countEngines); + void drawEngine(GraphicsContext gc, EntityAirFighter entityAirFighter, int startPosX, int startPosY); +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java new file mode 100644 index 0000000..a9277d2 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningAirFighter.java @@ -0,0 +1,66 @@ +package com.projectairfighter.drawnings; + +import com.projectairfighter.entities.EntityAirFighter; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.paint.Color; + +import java.util.Random; + +public class DrawningAirFighter extends DrawningWarPlane { + private final DrawableExtras engineDrawing; + + public DrawningAirFighter(int speed, double weight, Color bodyColor, Color + additionalColor, boolean bodyRockets, boolean additionalWings) { + super(speed, weight, bodyColor); + entityWarPlane = new EntityAirFighter(speed, weight, bodyColor, additionalColor, bodyRockets, additionalWings); + DrawableExtras[] engineDrawings = { + new EllipticalEngineDrawing(), + new TriangleEngineDrawing(), + new RectangleEngineDrawing() + }; + + Random random = new Random(); + engineDrawing = engineDrawings[random.nextInt(engineDrawings.length)]; + engineDrawing.setCountEngines(random.nextInt(7)); + } + + // Прорисовка объекта + @Override + public void drawTransport(GraphicsContext gc) { + if (entityWarPlane == null || !(entityWarPlane instanceof EntityAirFighter entityAirFighter) || getPosX() == null || getPosY() == null) { + return; + } + + gc.setStroke(entityAirFighter.getAdditionalColor()); + gc.setLineWidth(2); + + engineDrawing.drawEngine(gc, entityAirFighter, getPosX(), getPosY()); + + if (entityAirFighter.hasBodyRockets()) { + gc.setFill(entityAirFighter.getAdditionalColor()); + gc.setStroke(entityAirFighter.getAdditionalColor()); + + double rocketWidth = 6; + double rocketLength = 15; + + double[] rocketsX = {getPosX() + 100, getPosX() + 100}; + + for (double rocketPos : rocketsX) { + gc.fillRect(rocketPos, getPosY() + 13 - (rocketWidth / 2), rocketLength, rocketWidth); + gc.fillRect(rocketPos, getPosY() + 120 - (rocketWidth / 2), rocketLength, rocketWidth); + } + } + + if (entityAirFighter.hasAdditionalWings()) { + gc.setStroke(entityAirFighter.getAdditionalColor()); + double[] additionalWingTopX = {getPosX() + 40, getPosX() + 50, getPosX() + 60}; + double[] additionalWingTopY = {getPosY() + 53, getPosY() + 38, getPosY() + 53}; + double[] additionalWingBottomX = {getPosX() + 40, getPosX() + 50, getPosX() + 60}; + double[] additionalWingBottomY = {getPosY() + 80, getPosY() + 95, getPosY() + 80}; + + gc.strokePolygon(additionalWingTopX, additionalWingTopY, 3); + gc.strokePolygon(additionalWingBottomX, additionalWingBottomY, 3); + } + super.drawTransport(gc); + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java new file mode 100644 index 0000000..41fccda --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/DrawningWarPlane.java @@ -0,0 +1,145 @@ +package com.projectairfighter.drawnings; + +import com.projectairfighter.entities.EntityWarPlane; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.paint.Color; + +public class DrawningWarPlane { + // Сущность + public EntityWarPlane entityWarPlane; + + // Ширина и высота окна + private Integer pictureWidth = 0; + private Integer pictureHeight = 0; + + // Начальные координаты прорисовки истребителя + private Integer startPosX = null; + private Integer startPosY = null; + + private final int drawningAirFighterWidth = 157; + private final int drawningAirFighterHeight = 140; + + public Integer getPosX(){ + return startPosX; + } + public Integer getPosY(){ + return startPosY; + } + + public int getWidth(){ + return drawningAirFighterWidth; + } + public int getHeight(){ + return drawningAirFighterHeight; + } + + protected DrawningWarPlane() { + pictureWidth = 0; + pictureHeight = 0; + startPosX = null; + startPosY = null; + } + + public DrawningWarPlane(int speed, double weight, Color bodyColor) { + entityWarPlane = new EntityWarPlane(speed, weight, bodyColor); + } + + public boolean setPictureSize(int width, int height) { + if (width <= drawningAirFighterWidth || height <= drawningAirFighterHeight) return false; + pictureWidth = width; + pictureHeight = height; + if (startPosX != null && startPosY != null) { + if (startPosX + drawningAirFighterWidth > pictureWidth) { + startPosX = pictureWidth - drawningAirFighterWidth; + } + if (startPosY + drawningAirFighterHeight > pictureHeight) { + startPosY = pictureHeight - drawningAirFighterHeight; + } + } + return true; + } + + public void setPosition(int x, int y) { + if (pictureHeight == null || pictureWidth == null) return; + + startPosX = x; + startPosY = y; + + if (drawningAirFighterHeight + y > pictureHeight || y < 0) { + startPosY = 0; + } + if (drawningAirFighterWidth + x > pictureWidth || x < 0) { + startPosX = 0; + } + } + + public boolean moveTransport(DirectionType direction) { + if (entityWarPlane == null || startPosX == null || startPosY == null) return false; + + return switch (direction) { + case LEFT -> { + if (startPosX - entityWarPlane.getStep() > 0) { + startPosX -= (int) entityWarPlane.getStep(); + } + yield true; + } + case UP -> { + if (startPosY - entityWarPlane.getStep() > 0) { + startPosY -= (int) entityWarPlane.getStep(); + } + yield true; + } + case RIGHT -> { + if (startPosX + drawningAirFighterWidth + entityWarPlane.getStep() < pictureWidth) { + startPosX += (int) entityWarPlane.getStep(); + } + yield true; + } + case DOWN -> { + if (startPosY + drawningAirFighterHeight + entityWarPlane.getStep() < pictureHeight) { + startPosY += (int) entityWarPlane.getStep(); + } + yield true; + } + default -> false; + }; + } + + public void drawTransport(GraphicsContext gc) { + if (entityWarPlane == null || startPosX == null || startPosY == null) { + return; + } + + if (pictureWidth == 0 || pictureHeight == 0) return; + + gc.setFill(entityWarPlane.getBodyColor()); + gc.setStroke(entityWarPlane.getBodyColor()); + + // Прорисовка тела истребителя + gc.strokeRect(startPosX + 10, startPosY + 53, 130, 26); + + // Прорисовка носа + gc.fillPolygon( + new double[]{startPosX + 140, startPosX + 165, startPosX + 140}, + new double[]{startPosY + 53, startPosY + 66, startPosY + 79}, + 3 + ); + + // Прорисовка верхней части хвоста + gc.strokePolygon(new double[]{startPosX + 10, startPosX + 10, startPosX + 30, startPosX + 30}, + new double[]{startPosY + 23, startPosY + 53, startPosY + 53, startPosY + 38}, 4); + + // Прорисовка нижней части хвоста + gc.strokePolygon(new double[]{startPosX + 10, startPosX + 10, startPosX + 30, startPosX + 30}, + new double[]{startPosY + 79, startPosY + 109, startPosY + 94, startPosY + 79}, 4); + + // Прорисовка верхнего крыла + gc.strokePolygon(new double[]{startPosX + 100, startPosX + 100, startPosX + 70, startPosX + 85}, + new double[]{startPosY, startPosY + 53, startPosY + 53, startPosY}, 4); + + // Прорисовка нижнего крыла + gc.strokePolygon(new double[]{startPosX + 100, startPosX + 100, startPosX + 85, startPosX + 70}, + new double[]{startPosY + 79, startPosY + 133, startPosY + 133, startPosY + 79}, 4); + + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/EllipticalEngineDrawing.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/EllipticalEngineDrawing.java new file mode 100644 index 0000000..276d863 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/EllipticalEngineDrawing.java @@ -0,0 +1,72 @@ +package com.projectairfighter.drawnings; + +import com.projectairfighter.entities.EntityAirFighter; +import javafx.scene.canvas.GraphicsContext; + +public class EllipticalEngineDrawing implements DrawableExtras{ + private EngineCount engineCount; + + @Override + public void setCountEngines(int countEngines) { + switch (countEngines) { + case 4: + engineCount = EngineCount.FOUR; + break; + case 6: + engineCount = EngineCount.SIX; + break; + default: + engineCount = EngineCount.TWO; + break; + } + } + + @Override + public void drawEngine(GraphicsContext gc, EntityAirFighter entityAirFighter, int startPosX, int startPosY) { + double engineWidth = 6; + double engineHeight = 10; + double[] engineByTail; + double[] engineByWings; + gc.setFill(entityAirFighter.getAdditionalColor()); + + // Прорисовка двигателей в зависимости от их количества + switch (engineCount.getValue()) { + case 2: + engineByTail = new double[]{startPosX, startPosX}; + for (double rocketPos : engineByTail) { + gc.fillOval(rocketPos, startPosY + 42 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 90 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + } + break; + case 4: + engineByTail = new double[]{startPosX, startPosX, startPosX, startPosX}; + for (double rocketPos : engineByTail) { + gc.fillOval(rocketPos, startPosY + 28 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 53 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 78 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 103 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + } + break; + case 6: + engineHeight = 15; + engineByTail = new double[]{startPosX, startPosX, startPosX, startPosX, startPosX, startPosX}; + engineByWings = new double[]{startPosX + 65, startPosX + 65}; + + for (double rocketPos : engineByWings) { + gc.fillOval(rocketPos, startPosY + 28 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 107 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + } + + engineHeight = 10; + + for (double rocketPos : engineByTail) { + gc.fillOval(rocketPos, startPosY + 28 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 53 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 78 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + gc.fillOval(rocketPos, startPosY + 103 - (engineWidth / 2), engineHeight, engineWidth); // Круглый двигатель + } + break; + } + + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/EngineCount.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/EngineCount.java similarity index 82% rename from ProjectAirFighter/src/main/java/com/projectairfighter/EngineCount.java rename to ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/EngineCount.java index 196f466..a7f6f00 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/EngineCount.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/EngineCount.java @@ -1,4 +1,4 @@ -package com.projectairfighter; +package com.projectairfighter.drawnings; public enum EngineCount { TWO(2), diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/EngineDrawing.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/RectangleEngineDrawing.java similarity index 89% rename from ProjectAirFighter/src/main/java/com/projectairfighter/EngineDrawing.java rename to ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/RectangleEngineDrawing.java index b159608..11a47b8 100644 --- a/ProjectAirFighter/src/main/java/com/projectairfighter/EngineDrawing.java +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/RectangleEngineDrawing.java @@ -1,12 +1,13 @@ -package com.projectairfighter; +package com.projectairfighter.drawnings; +import com.projectairfighter.entities.EntityAirFighter; import javafx.scene.canvas.GraphicsContext; -public class EngineDrawing { - +public class RectangleEngineDrawing implements DrawableExtras { private EngineCount engineCount; - public void setCountEngines(int countEngines){ + @Override + public void setCountEngines(int countEngines) { switch (countEngines) { case 4: engineCount = EngineCount.FOUR; @@ -20,18 +21,18 @@ public class EngineDrawing { } } - public void drawEngine(GraphicsContext gc, EntityAirFighter entityAirFighter, double startPosX, double startPosY){ + @Override + public void drawEngine(GraphicsContext gc, EntityAirFighter entityAirFighter, int startPosX, int startPosY) { double engineWidth = 6; double engineHeight = 10; double[] engineByTail; double[] engineByWings; - gc.setStroke(entityAirFighter.getAdditionalColor()); + gc.setFill(entityAirFighter.getAdditionalColor()); // Прорисовка двигателей в зависимости от их количества switch (engineCount.getValue()) { case 2: engineByTail = new double[]{startPosX, startPosX}; // Изменено - for (double rocketPos : engineByTail) { gc.fillRect(rocketPos, startPosY + 42 - (engineWidth / 2), engineHeight, engineWidth); gc.fillRect(rocketPos, startPosY + 90 - (engineWidth / 2), engineHeight, engineWidth); @@ -39,7 +40,6 @@ public class EngineDrawing { break; case 4: engineByTail = new double[]{startPosX, startPosX, startPosX, startPosX}; - for (double rocketPos : engineByTail) { gc.fillRect(rocketPos, startPosY + 28 - (engineWidth / 2), engineHeight, engineWidth); gc.fillRect(rocketPos, startPosY + 53 - (engineWidth / 2), engineHeight, engineWidth); @@ -65,8 +65,7 @@ public class EngineDrawing { gc.fillRect(rocketPos, startPosY + 78 - (engineWidth / 2), engineHeight, engineWidth); gc.fillRect(rocketPos, startPosY + 103 - (engineWidth / 2), engineHeight, engineWidth); } - break; } } -} +} \ No newline at end of file diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/TriangleEngineDrawing.java b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/TriangleEngineDrawing.java new file mode 100644 index 0000000..a47ca64 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/drawnings/TriangleEngineDrawing.java @@ -0,0 +1,83 @@ +package com.projectairfighter.drawnings; + +import com.projectairfighter.entities.EntityAirFighter; +import javafx.scene.canvas.GraphicsContext; + +public class TriangleEngineDrawing implements DrawableExtras { + private EngineCount engineCount; + + @Override + public void setCountEngines(int countEngines) { + switch (countEngines) { + case 4: + engineCount = EngineCount.FOUR; + break; + case 6: + engineCount = EngineCount.SIX; + break; + default: + engineCount = EngineCount.TWO; + break; + } + } + + @Override + public void drawEngine(GraphicsContext gc, EntityAirFighter entityAirFighter, int startPosX, int startPosY) { + double engineWidth = 6; + double engineHeight = 10; + double[] engineByTail; + double[] engineByWings; + gc.setFill(entityAirFighter.getAdditionalColor()); + + // Прорисовка двигателей в зависимости от их количества + switch (engineCount.getValue()) { + case 2: + engineByTail = new double[]{startPosX - 3, startPosX - 3}; // Изменено + for (double rocketPos : engineByTail) { + drawTriangle(gc, rocketPos, startPosY + 42, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 90, engineHeight, engineWidth); + } + break; + case 4: + engineByTail = new double[]{startPosX - 3, startPosX - 3, startPosX - 3, startPosX - 3}; + for (double rocketPos : engineByTail) { + drawTriangle(gc, rocketPos, startPosY + 28, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 53, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 78, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 103, engineHeight, engineWidth); + } + break; + case 6: + engineHeight = 15; + engineByTail = new double[]{startPosX, startPosX, startPosX, startPosX, startPosX, startPosX}; + engineByWings = new double[]{startPosX + 61, startPosX + 61}; + + for (double rocketPos : engineByWings) { + drawTriangle(gc, rocketPos, startPosY + 28, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 107, engineHeight, engineWidth); + } + + engineHeight = 10; + + for (double rocketPos : engineByTail) { + drawTriangle(gc, rocketPos, startPosY + 28, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 53, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 78, engineHeight, engineWidth); + drawTriangle(gc, rocketPos, startPosY + 103, engineHeight, engineWidth); + } + break; + } + } + + private void drawTriangle(GraphicsContext gc, double x, double y, double height, double width) { + double halfHeight = height * 1.2; // Увеличиваем высоту на 20% + double halfWidth = width * 1.2; // Увеличиваем ширину на 20% + + gc.beginPath(); + gc.moveTo(x, y); + gc.lineTo(x + halfHeight, y - halfWidth / 2); + gc.lineTo(x + halfHeight, y + halfWidth / 2); + gc.closePath(); + gc.fill(); + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java new file mode 100644 index 0000000..9cbaaad --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityAirFighter.java @@ -0,0 +1,33 @@ +package com.projectairfighter.entities; + +import javafx.scene.paint.Color; + +public class EntityAirFighter extends EntityWarPlane { + // Дополнительный цвет (для опциональных элементов) + private final Color additionalColor; + // Признак (опция) наличия ракет + private final boolean bodyRockets; + // Признак (опция) наличия дополнительных крыльев + private final boolean additionalWings; + + public Color getAdditionalColor() { + return additionalColor; + } + + public boolean hasBodyRockets() { + return bodyRockets; + } + + public boolean hasAdditionalWings() { + return additionalWings; + } + + // Конструктор + public EntityAirFighter(int speed, double weight, Color bodyColor, Color + additionalColor, boolean bodyRockets, boolean additionalWings){ + super(speed, weight, bodyColor); + this.additionalColor = additionalColor; + this.bodyRockets = bodyRockets; + this.additionalWings = additionalWings; + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityWarPlane.java b/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityWarPlane.java new file mode 100644 index 0000000..e7d3551 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/entities/EntityWarPlane.java @@ -0,0 +1,26 @@ +package com.projectairfighter.entities; + +import javafx.scene.paint.Color; + +public class EntityWarPlane { + // Скорость + private final int speed; + // Вес + private final double weight; + // Основной цвет + private final Color bodyColor; + + public double getStep() { + return speed * 100 / weight; + } + + public Color getBodyColor() { + return bodyColor; + } + + public EntityWarPlane(int speed, double weight, Color bodyColor){ + this.speed = speed; + this.weight = weight; + this.bodyColor = bodyColor; + } +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/AbstractStrategy.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/AbstractStrategy.java new file mode 100644 index 0000000..8dfb711 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/AbstractStrategy.java @@ -0,0 +1,91 @@ +package com.projectairfighter.movementstrategy; + +public abstract class AbstractStrategy { + // Перемещаемый объект + private IMoveableObject moveableObject; + + // Статус перемещения + private StrategyStatus state = StrategyStatus.NotInit; + + // Ширина поля + protected int fieldWidth; + + // Высота поля + protected int fieldHeight; + + // Конструктор + public AbstractStrategy() {} + + // Установка данных + public void setData(IMoveableObject moveableObject, int width, int height) { + if (moveableObject == null) { + state = StrategyStatus.NotInit; + return; + } + + state = StrategyStatus.InProgress; + this.moveableObject = moveableObject; + fieldHeight = height; + fieldWidth = width; + } + + // Получение статуса перемещения + public StrategyStatus getStatus() { + return state; + } + + // Шаг перемещения + public void makeStep() { + if (state != StrategyStatus.InProgress) { + return; + } + if (isTargetDestination()) { + state = StrategyStatus.Finish; + return; + } + moveToTarget(); + } + + // Параметры объекта + protected ObjectParameters getObjectParameters() { + return moveableObject != null ? moveableObject.getObjectPosition() : null; + } + + // Шаг объекта + protected Integer getStep() { + return state == StrategyStatus.InProgress ? moveableObject.getStep() : null; + } + + // Перемещение влево + protected boolean moveLeft() { + return move(MovementDiraction.Left); + } + + // Перемещение вправо + protected boolean moveRight() { + return move(MovementDiraction.Right); + } + + // Перемещение вверх + protected boolean moveUp() { + return move(MovementDiraction.Up); + } + + // Перемещение вниз + protected boolean moveDown() { + return move(MovementDiraction.Down); + } + + // Попытка перемещения в требуемом направлении + private boolean move(MovementDiraction direction) { + if (state != StrategyStatus.InProgress) { + return false; + } + return moveableObject.tryMoveObject(direction); + } + + // Абстрактные методы, которые должны быть реализованы в подклассах + protected abstract void moveToTarget(); + protected abstract boolean isTargetDestination(); +} + diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/IMoveableObject.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/IMoveableObject.java new file mode 100644 index 0000000..18a3a8f --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/IMoveableObject.java @@ -0,0 +1,13 @@ +package com.projectairfighter.movementstrategy; + +public interface IMoveableObject { + // Получение координаты объекта + ObjectParameters getObjectPosition(); + + // Шаг объекта + int getStep(); + + // Попытка переместить объект в указанном направлении + boolean tryMoveObject(MovementDiraction direction); +} + diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveToBorder.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveToBorder.java new file mode 100644 index 0000000..04ac70e --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveToBorder.java @@ -0,0 +1,36 @@ +package com.projectairfighter.movementstrategy; + +public class MoveToBorder extends AbstractStrategy { + @Override + protected boolean isTargetDestination() { + ObjectParameters objParams = getObjectParameters(); + if (objParams == null) { + return false; + } + return objParams.getRightBorder() + getStep() >= fieldWidth && objParams.getDownBorder() + getStep() >= fieldHeight; + } + + @Override + protected void moveToTarget() { + ObjectParameters objParams = getObjectParameters(); + if (objParams == null) { + return; + } + int diffX = objParams.getRightBorder() - fieldWidth; + if (Math.abs(diffX) > getStep()) { + if (diffX > 0) { + moveLeft(); + } else { + moveRight(); + } + } + int diffY = objParams.getDownBorder() - fieldHeight; + if (Math.abs(diffY) > getStep()) { + if (diffY > 0) { + moveUp(); + } else { + moveDown(); + } + } + } +} \ No newline at end of file diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveToCenter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveToCenter.java new file mode 100644 index 0000000..9d5adff --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveToCenter.java @@ -0,0 +1,41 @@ +package com.projectairfighter.movementstrategy; + +public class MoveToCenter extends AbstractStrategy { + @Override + protected boolean isTargetDestination() { + ObjectParameters objParams = getObjectParameters(); + if (objParams == null) { + return false; + } + + return objParams.getObjectMiddleHorizontal() - getStep() <= fieldWidth / 2 && objParams.getObjectMiddleHorizontal() + getStep() >= fieldWidth / 2 && + objParams.getObjectMiddleVertical() - getStep() <= fieldHeight / 2 && objParams.getObjectMiddleVertical() + getStep() >= fieldHeight / 2; + } + + @Override + protected void moveToTarget() { + ObjectParameters objParams = getObjectParameters(); + if (objParams == null) { + return; + } + + int diffX = objParams.getObjectMiddleHorizontal() - fieldWidth / 2; + if (Math.abs(diffX) > getStep()) { + if (diffX > 0) { + moveLeft(); + } else { + moveRight(); + } + } + + int diffY = objParams.getObjectMiddleVertical() - fieldHeight / 2; + if (Math.abs(diffY) > getStep()) { + if (diffY > 0) { + moveUp(); + } else { + moveDown(); + } + } + } +} + diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveableFighter.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveableFighter.java new file mode 100644 index 0000000..fa78a10 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MoveableFighter.java @@ -0,0 +1,49 @@ +package com.projectairfighter.movementstrategy; + +import com.projectairfighter.drawnings.DirectionType; +import com.projectairfighter.drawnings.DrawningWarPlane; + +public class MoveableFighter implements IMoveableObject { + // Поле-объект класса DrawningWarPlane или его наследника + private final DrawningWarPlane warPlane; + + // Конструктор + public MoveableFighter(DrawningWarPlane drawningFighter) { + this.warPlane = drawningFighter; + } + + @Override + public ObjectParameters getObjectPosition() { + if (warPlane == null || warPlane.entityWarPlane == null || warPlane.getPosX() == null || warPlane.getPosY() == null) { + return null; + } + + return new ObjectParameters(warPlane.getPosX(), warPlane.getPosY(), warPlane.getWidth(), warPlane.getHeight()); + } + + @Override + public int getStep() { + return (int) (warPlane != null && warPlane.entityWarPlane != null ? warPlane.entityWarPlane.getStep() : 0); + } + + @Override + public boolean tryMoveObject(MovementDiraction direction) { + if (warPlane == null || warPlane.entityWarPlane == null) { + return false; + } + + return warPlane.moveTransport(getDirectionType(direction)); + } + + // Конвертация из MovementDirection в DirectionType + private static DirectionType getDirectionType(MovementDiraction diraction) { + return switch (diraction) { + case Left -> DirectionType.LEFT; + case Right -> DirectionType.RIGHT; + case Up -> DirectionType.UP; + case Down -> DirectionType.DOWN; + default -> DirectionType.UNKNOWN; + }; + } +} + diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MovementDiraction.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MovementDiraction.java new file mode 100644 index 0000000..d04cc62 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/MovementDiraction.java @@ -0,0 +1,11 @@ +package com.projectairfighter.movementstrategy; + +public enum MovementDiraction { + Up, + + Down, + + Left, + + Right +} diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/ObjectParameters.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/ObjectParameters.java new file mode 100644 index 0000000..0650196 --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/ObjectParameters.java @@ -0,0 +1,40 @@ +package com.projectairfighter.movementstrategy; + +public class ObjectParameters { + private final int x; + private final int y; + private final int width; + private final int height; + + public ObjectParameters(int x, int y, int width, int height) { + this.x = x; + this.y = y; + this.width = width; + this.height = height; + } + + public int getLeftBorder() { + return x; + } + + public int getTopBorder() { + return y; + } + + public int getRightBorder() { + return x + width; + } + + public int getDownBorder() { + return y + height; + } + + public int getObjectMiddleHorizontal() { + return x + width / 2; + } + + public int getObjectMiddleVertical() { + return y + height / 2; + } +} + diff --git a/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/StrategyStatus.java b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/StrategyStatus.java new file mode 100644 index 0000000..a1915ba --- /dev/null +++ b/ProjectAirFighter/src/main/java/com/projectairfighter/movementstrategy/StrategyStatus.java @@ -0,0 +1,13 @@ +package com.projectairfighter.movementstrategy; + +public enum StrategyStatus { + // Все готово к началу + NotInit, + + // Выполняется + InProgress, + + // Завершено + Finish +} + diff --git a/ProjectAirFighter/src/main/java/module-info.java b/ProjectAirFighter/src/main/java/module-info.java index 6b6900c..e03e313 100644 --- a/ProjectAirFighter/src/main/java/module-info.java +++ b/ProjectAirFighter/src/main/java/module-info.java @@ -6,4 +6,10 @@ module com.projectairfighter { opens com.projectairfighter to javafx.fxml; exports com.projectairfighter; + exports com.projectairfighter.drawnings; + opens com.projectairfighter.drawnings to javafx.fxml; + exports com.projectairfighter.entities; + opens com.projectairfighter.entities to javafx.fxml; + exports com.projectairfighter.movementstrategy; + opens com.projectairfighter.movementstrategy to javafx.fxml; } \ No newline at end of file diff --git a/ProjectAirFighter/src/main/resources/com/projectairfighter/Form.fxml b/ProjectAirFighter/src/main/resources/com/projectairfighter/Form.fxml index 48d9332..246c894 100644 --- a/ProjectAirFighter/src/main/resources/com/projectairfighter/Form.fxml +++ b/ProjectAirFighter/src/main/resources/com/projectairfighter/Form.fxml @@ -5,7 +5,7 @@ - + -