diff --git a/src/main/java/lab/BulletAnimated.java b/src/main/java/lab/BulletAnimated.java index 02b9a3208dfb390973e21995e808951864d11bae..cc7d236ffe7f1320897d2958303506ac5842c994 100644 --- a/src/main/java/lab/BulletAnimated.java +++ b/src/main/java/lab/BulletAnimated.java @@ -1,6 +1,7 @@ package lab; import javafx.geometry.Point2D; +import javafx.geometry.Rectangle2D; import javafx.scene.canvas.GraphicsContext; import javafx.scene.image.Image; @@ -19,6 +20,7 @@ public class BulletAnimated { public void draw(GraphicsContext gc) { gc.drawImage(image, getPosition().getX(), getPosition().getY(), SIZE, SIZE); + gc.strokeRect(position.getX(), position.getY(), SIZE, SIZE); } private final Point2D acceleration; @@ -35,4 +37,8 @@ public class BulletAnimated { return position; } + public Rectangle2D getBoundingBox() { + return new Rectangle2D(position.getX(), position.getY(), SIZE,SIZE); + } + } diff --git a/src/main/java/lab/Ufo.java b/src/main/java/lab/Ufo.java new file mode 100644 index 0000000000000000000000000000000000000000..472c4f1920b7d8b5289eb3b998b7f5a35c198255 --- /dev/null +++ b/src/main/java/lab/Ufo.java @@ -0,0 +1,50 @@ +package lab; + +import java.util.Random; + +import javafx.geometry.Point2D; +import javafx.geometry.Rectangle2D; +import javafx.scene.canvas.GraphicsContext; +import javafx.scene.image.Image; + +public class Ufo { + + private static final Random RANDOM = new Random(); + private Image image = new Image(this.getClass().getResourceAsStream("ufo-small.gif")); + private final World world; + private Point2D position; + private Point2D velocity; + + public Ufo(World world) { + this(world, + new Point2D(RANDOM.nextDouble(world.getWidth()), + RANDOM.nextDouble(0, world.getHeight()*0.3)), + new Point2D(RANDOM.nextDouble(70, 150), 0)); + } + + public Ufo(World world, Point2D position, Point2D velocity) { + this.world = world; + this.position = position; + this.velocity = velocity; + } + + public void draw(GraphicsContext gc) { + gc.drawImage(image, getPosition().getX(), getPosition().getY()); + } + + public void changeDirection(){ + velocity = velocity.multiply(-1); + } + public void simulate(double deltaT) { + position = position.add(velocity.multiply(deltaT)); + position = new Point2D(position.getX()%world.getWidth(), position.getY()); + } + + protected Point2D getPosition() { + return position; + } + + public Rectangle2D getBoundingBox() { + return new Rectangle2D(position.getX(), position.getY(), image.getWidth(), image.getHeight()); + } +} diff --git a/src/main/java/lab/World.java b/src/main/java/lab/World.java index 3417a426a6350a8de5e55c437b5c22aa381d7225..6abd918876c6fdc2cd0552120a9b929735388ad9 100644 --- a/src/main/java/lab/World.java +++ b/src/main/java/lab/World.java @@ -1,5 +1,7 @@ package lab; +import java.util.Iterator; + import javafx.geometry.Point2D; import javafx.scene.canvas.GraphicsContext; @@ -12,6 +14,7 @@ public class World { private final Bullet bullet; private final BulletAnimated bullet2; private final Cannon cannon; + private Ufo[] ufos; public World(double width, double height) { this.width = width; @@ -19,6 +22,10 @@ public class World { bullet = new Bullet(this, new Point2D(0, height), new Point2D(30, -30), new Point2D(0, 9.81)); bullet2 = new BulletAnimated(this, new Point2D(0, height), new Point2D(50, -80), new Point2D(0, 9.81)); cannon = new Cannon(this, new Point2D(0, height-20), -45); + ufos = new Ufo[5]; + for (int i = 0; i < ufos.length; i++) { + ufos[i] = new Ufo(this); + } } public void draw(GraphicsContext gc) { @@ -28,6 +35,9 @@ public class World { bullet.draw(gc); bullet2.draw(gc); cannon.draw(gc); + for (int i = 0; i < ufos.length; i++) { + ufos[i].draw(gc); + } gc.restore(); } @@ -35,6 +45,14 @@ public class World { bullet.simulate(deltaT); bullet2.simulate(deltaT); cannon.simulate(deltaT); + for (int i = 0; i < ufos.length; i++) { + ufos[i].simulate(deltaT); + } + for (Ufo ufo : ufos) { + if(ufo.getBoundingBox().intersects(bullet2.getBoundingBox())) { + ufo.changeDirection(); + } + } } public double getWidth() { diff --git a/src/main/resources/lab/ufo-small.gif b/src/main/resources/lab/ufo-small.gif new file mode 100644 index 0000000000000000000000000000000000000000..a1aca24e41f2d04912a45c703663c2b607f722dd Binary files /dev/null and b/src/main/resources/lab/ufo-small.gif differ diff --git a/src/main/resources/lab/ufo.gif b/src/main/resources/lab/ufo.gif new file mode 100644 index 0000000000000000000000000000000000000000..d07613c8999847572bffb44d7b161cffd874ca0f Binary files /dev/null and b/src/main/resources/lab/ufo.gif differ diff --git a/src/test/java/jez04/structure/test/ClassStructureTest.java b/src/test/java/jez04/structure/test/ClassStructureTest.java new file mode 100644 index 0000000000000000000000000000000000000000..ac5f14c0fe6cce1adc3586795317ea18888dc5fa --- /dev/null +++ b/src/test/java/jez04/structure/test/ClassStructureTest.java @@ -0,0 +1,117 @@ +package jez04.structure.test; + +import static org.junit.jupiter.api.Assertions.assertNotNull; +import static org.junit.jupiter.api.Assertions.assertTrue; + +import java.lang.reflect.Constructor; +import java.lang.reflect.Field; +import java.lang.reflect.Method; +import java.util.Arrays; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +import org.junit.jupiter.api.Test; +import org.reflections.Configuration; +import org.reflections.Reflections; +import org.reflections.scanners.Scanners; +import org.reflections.util.ConfigurationBuilder; + +import javafx.geometry.Rectangle2D; + +class ClassStructureTest { + + @Test + void ufoClassEexistanceTest() { + Set<String> allClasses = getNameOfAllClasses(); + assertTrue(allClasses.stream().anyMatch(c -> c.endsWith("Ufo")), "Class Ufo not found"); + } + + @Test + void ufoClassPropertiesTest() { + Set<String> allClasses = getNameOfAllClasses(); + String ufoClassName = allClasses.stream().filter(c -> c.endsWith("Ufo")).findAny().orElse(null); + assertNotNull(ufoClassName, "Class Ufo not found"); + try { + Class<?> ufoClass = Class.forName(ufoClassName); + List<Method> methods = Arrays.asList(ufoClass.getMethods()); + assertTrue(methods.stream().anyMatch(m -> m.getName().contains("draw")), "No method draw"); + assertTrue(methods.stream().anyMatch(m -> m.getName().contains("simulate")), "No method simulate"); + assertTrue(methods.stream().anyMatch(m -> m.getName().contains("getBoundingBox")), + "No method getBoundingBox"); + assertTrue( + methods.stream().filter(m -> m.getName().contains("getBoundingBox")) + .anyMatch(m -> m.getReturnType().equals(Rectangle2D.class)), + "Method getBoundingBox not return Rectangle2D"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + @Test + void worldClassPropertyTest() { + Set<String> allClasses = getNameOfAllClasses(); + String ufoClassName = allClasses.stream().filter(c -> c.endsWith("Ufo")).findAny().orElse(null); + String worldClassName = allClasses.stream().filter(c -> c.endsWith("World")).findAny().orElse(null); + assertNotNull(worldClassName, "Class World not found"); + try { + Class<?> worldClass = Class.forName(worldClassName); + List<Field> fields = Arrays.asList(worldClass.getDeclaredFields()); + Class<?> ufoClass = Class.forName(ufoClassName); + assertTrue( + fields.stream() + .anyMatch(f -> f.getType().isArray() && f.getType().getComponentType().equals(ufoClass)), + "No array of Ufo in World class"); + } catch (ClassNotFoundException e) { + e.printStackTrace(); + } + } + + @Test + void drawingClassExistenceTest() { + Set<String> allClasses = getNameOfAllClasses(); + int detectedClassCount = 0; + for (String className : allClasses) { + try { + Class<?> clazz = Class.forName(className); + List<Constructor<?>> constructorList = Arrays.asList(clazz.getConstructors()); + List<Method> methodList = Arrays.asList(clazz.getMethods()); + long drawMethodCount = methodList.stream().filter(m -> m.getName().contains("draw")).count(); + long simulateMethodCount = methodList.stream().filter(m -> m.getName().contains("sim")).count(); + if (!constructorList.isEmpty() && (drawMethodCount > 0 || simulateMethodCount > 0)) { + System.out.println("DETECT:" + className); + detectedClassCount++; + } + } catch (ClassNotFoundException e) { + System.out.println(String.format("Class '%s' cannot be loaded: %s", className, e.getMessage())); + } + } + assertTrue(detectedClassCount >= 2, ""); + } + + private Set<String> getNameOfAllClasses() { + List<String> initClassesName = Arrays.asList("lab.Routines", "lab.App", "lab.DrawingThread"); + for (String className : initClassesName) { + try { + Class.forName(className); + } catch (ClassNotFoundException e) { + System.out.println(String.format("Class '%s' cannot be loaded: %s", className, e.getMessage())); + } + } + Set<String> allClasses = new HashSet<>(); + for (Package p : Package.getPackages()) { + if (p.getName().startsWith("java.") || p.getName().startsWith("com.") || p.getName().startsWith("jdk.") + || p.getName().startsWith("javafx.") || p.getName().startsWith("org.") + || p.getName().startsWith("sun.") || p.getName().startsWith("javax.") + || p.getName().startsWith("javassist")) { + continue; + } + System.out.println(p.getName()); + Configuration conf = new ConfigurationBuilder().addScanners(Scanners.SubTypes.filterResultsBy(pc -> true)) + .forPackages(p.getName()); + Reflections reflections = new Reflections(conf); + allClasses.addAll(reflections.getAll(Scanners.SubTypes.filterResultsBy(c -> true))); + } + return allClasses; + } +}