Skip to content
Snippets Groups Projects
Commit f23e74f9 authored by jez04's avatar jez04
Browse files

feat: 🎉 solution

parent fc01b326
No related merge requests found
package lab;
import javafx.animation.AnimationTimer;
import javafx.application.Application;
import javafx.scene.Group;
import javafx.fxml.FXMLLoader;
import javafx.scene.Parent;
import javafx.scene.Scene;
import javafx.scene.canvas.Canvas;
import javafx.stage.Stage;
import javafx.stage.WindowEvent;
......@@ -16,31 +15,25 @@ import javafx.stage.WindowEvent;
*/
public class App extends Application {
private GameController gameController;
public static void main(String[] args) {
launch(args);
}
private Canvas canvas;
private AnimationTimer timer;
@Override
public void start(Stage primaryStage) {
try {
// Construct a main window with a canvas.
Group root = new Group();
canvas = new Canvas(800, 400);
root.getChildren().add(canvas);
Scene scene = new Scene(root, 800, 400);
scene.getStylesheets().add(getClass().getResource("application.css").toExternalForm());
FXMLLoader gameLoader = new FXMLLoader(getClass().getResource("/lab/gameWindow.fxml"));
Parent root = gameLoader.load();
GameController gameController = gameLoader.getController();
Scene scene = new Scene(root);
primaryStage.setScene(scene);
primaryStage.resizableProperty().set(false);
primaryStage.setTitle("Java 1 - 1th laboratory");
primaryStage.show();
// Exit program when main window is closed
primaryStage.setOnCloseRequest(this::exitProgram);
timer = new DrawingThread(canvas);
timer.start();
} catch (Exception e) {
e.printStackTrace();
}
......@@ -48,7 +41,7 @@ public class App extends Application {
@Override
public void stop() throws Exception {
timer.stop();
gameController.stop();
super.stop();
}
......
......@@ -44,4 +44,8 @@ public class Bullet extends WorldEntity implements Collisionable{
}
public void setVelocity(Point2D velocity) {
this.velocity = velocity;
}
}
......@@ -33,7 +33,7 @@ public class BulletAnimated extends Bullet {
public void reload() {
position = cannon.getPosition();
velocity = initVelocity;
velocity = new Point2D(0, 0);
}
}
\ No newline at end of file
......@@ -27,9 +27,18 @@ public class Cannon extends WorldEntity{
@Override
public void simulate(double deltaT) {
angle += angleDelta * deltaT;
if (angle >= 0 || angle <= -90) {
angleDelta = -angleDelta;
}
// angle += angleDelta * deltaT;
// if (angle >= 0 || angle <= -90) {
// angleDelta = -angleDelta;
// }
}
public double getAngle() {
return angle;
}
public void setAngle(double angle) {
this.angle = -angle;
}
}
......@@ -31,4 +31,8 @@ public class DrawingThread extends AnimationTimer {
lastTime = now;
}
public World getWorld() {
return world;
}
}
package lab;
import javafx.beans.value.ChangeListener;
import javafx.beans.value.ObservableValue;
import javafx.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Point2D;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Slider;
public class GameController {
@FXML
private Slider angle;
@FXML
private Slider speed;
@FXML
private Canvas canvas;
private DrawingThread timer;
@FXML
void fire(ActionEvent event) {
double angle = timer.getWorld().getCannon().getAngle();
double angleRad = Math.toRadians(angle);
double speedValue = speed.getValue();
timer.getWorld().getBulletAnimated().reload();
Point2D velocity = new Point2D(
Math.cos(angleRad)*speedValue,
Math.sin(angleRad)*speedValue);
timer.getWorld().getBulletAnimated().setVelocity(velocity);
}
@FXML
void initialize() {
assert angle != null : "fx:id=\"angle\" was not injected: check your FXML file 'gameWindow.fxml'.";
assert canvas != null : "fx:id=\"canvas\" was not injected: check your FXML file 'gameWindow.fxml'.";
assert speed != null : "fx:id=\"speed\" was not injected: check your FXML file 'gameWindow.fxml'.";
timer = new DrawingThread(canvas);
timer.start();
angle.valueProperty().addListener(new ChangeListener<Number>() {
@Override
public void changed(ObservableValue<? extends Number> observable, Number oldValue, Number newValue) {
timer.getWorld().getCannon().setAngle(newValue.doubleValue());
}
});
}
public void stop() {
timer.stop();
}
}
......@@ -12,16 +12,19 @@ public class World {
private final double height;
private DrawableSimulable[] entities;
private Cannon cannon;
private BulletAnimated bulletAnimated;
public World(double width, double height) {
this.width = width;
this.height = height;
entities = new DrawableSimulable[8];
Cannon cannon = new Cannon(this, new Point2D(0, height - 20), -45);
cannon = new Cannon(this, new Point2D(0, height - 20), -45);
bulletAnimated = new BulletAnimated(this, cannon, new Point2D(0, height), new Point2D(50, -80),
new Point2D(0, 9.81));
entities[0] = cannon;
entities[1] = new Bullet(this, new Point2D(0, height), new Point2D(30, -30), new Point2D(0, 9.81));
entities[2] = new BulletAnimated(this, cannon, new Point2D(0, height), new Point2D(50, -80),
new Point2D(0, 9.81));
entities[2] = bulletAnimated;
for (int i = 3; i < entities.length; i++) {
entities[i] = new Ufo(this);
}
......@@ -63,4 +66,12 @@ public class World {
return height;
}
public Cannon getCannon() {
return cannon;
}
public BulletAnimated getBulletAnimated() {
return bulletAnimated;
}
}
\ No newline at end of file
<?xml version="1.0" encoding="UTF-8"?>
<?import javafx.geometry.Insets?>
<?import javafx.scene.Cursor?>
<?import javafx.scene.canvas.Canvas?>
<?import javafx.scene.control.Button?>
<?import javafx.scene.control.Slider?>
<?import javafx.scene.layout.BorderPane?>
<?import javafx.scene.layout.HBox?>
<?import javafx.scene.text.Font?>
<BorderPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="400.0" prefWidth="600.0" xmlns="http://javafx.com/javafx/21" xmlns:fx="http://javafx.com/fxml/1" fx:controller="lab.GameController">
<bottom>
<HBox alignment="TOP_CENTER" prefHeight="100.0" prefWidth="200.0" BorderPane.alignment="CENTER">
<children>
<Slider fx:id="angle" majorTickUnit="15.0" max="90.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minorTickCount="5" showTickLabels="true" showTickMarks="true" HBox.hgrow="ALWAYS" />
<Button mnemonicParsing="false" onAction="#fire" style="-fx-background-color: RED;" text="Fire" textAlignment="CENTER">
<font>
<Font name="System Bold" size="24.0" />
</font>
<cursor>
<Cursor fx:constant="CROSSHAIR" />
</cursor>
<opaqueInsets>
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
</opaqueInsets>
<HBox.margin>
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
</HBox.margin>
</Button>
<Slider fx:id="speed" max="200.0" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" min="50.0" minorTickCount="5" showTickLabels="true" showTickMarks="true" value="50.0" HBox.hgrow="ALWAYS" />
</children>
</HBox>
</bottom>
<center>
<Canvas fx:id="canvas" height="287.0" width="582.0" BorderPane.alignment="CENTER">
<BorderPane.margin>
<Insets />
</BorderPane.margin>
</Canvas>
</center>
</BorderPane>
package jez04.structure.test;
import static org.junit.jupiter.api.Assertions.assertNotNull;
import static org.junit.jupiter.api.Assertions.assertTrue;
import java.io.ByteArrayOutputStream;
import java.io.PrintStream;
import java.lang.reflect.Constructor;
import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import org.junit.jupiter.api.Assertions;
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.event.ActionEvent;
import javafx.fxml.FXML;
import javafx.geometry.Rectangle2D;
import javafx.scene.canvas.GraphicsContext;
class ClassStructureTest {
private static final String drawableSimulableName = "DrawableSimulable";
private static final String collisionableName = "Collisionable";
Set<String> allClasses = getNameOfAllClasses();
@Test
void ufoClassEexistanceTest() {
Set<String> allClasses = getNameOfAllClasses();
assertTrue(allClasses.stream().anyMatch(c -> c.endsWith("Ufo")), "Class Ufo not found");
void gameControllerExistenceTest() {
classExist("GameController");
Class<?> c = getClass("GameController");
hasPropertyWithAnnotation(c, ".*", FXML.class);
hasMethodRegexp(c, ".*", void.class, ActionEvent.class);
}
@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();
}
void gameControllerFxmlTest() {
classExist("GameController");
Class<?> c = getClass("GameController");
hasPropertyWithAnnotation(c, ".*", FXML.class);
}
@Test
void gameControllerActionEventTest() {
classExist("GameController");
Class<?> c = getClass("GameController");
hasMethodRegexp(c, ".*", void.class, ActionEvent.class);
}
@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");
void cannonExistenceTest() {
classExist("Cannon");
}
@Test
void cannonExistenceSetAngleTest() {
classExist("Cannon");
Class<?> c = getClass("Cannon");
hasMethod(c, "setAngle");
}
private void isInterface(Class<?> c) {
assertTrue(c.isInterface(), c.getName() + " have to be interface.");
}
private void classExist(String name) {
assertTrue(allClasses.stream().anyMatch(c -> c.endsWith(name)), "Interface " + name + " not found");
}
private Class<?> getClass(String name) {
String className = allClasses.stream().filter(c -> c.endsWith(name)).findAny().orElse(null);
if (className == null) {
Assertions.fail("Class " + name + " 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");
return Class.forName(className);
} catch (ClassNotFoundException e) {
e.printStackTrace();
final ByteArrayOutputStream baos = new ByteArrayOutputStream();
try (PrintStream ps = new PrintStream(baos, true)) {
e.printStackTrace(ps);
} catch (Exception e2) {
Assertions.fail(e2.getMessage());
}
String stackTrace = baos.toString();
Assertions.fail("Class " + name + " not found.\n" + stackTrace);
return null;
}
}
@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++;
private void hasProperty(Class<?> classDef, String propertyNameRegexp, Class<?> type, boolean array) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(fields.stream().anyMatch(f -> {
if (f.getName().matches(propertyNameRegexp)) {
if (array) {
return f.getType().isArray() && f.getType().getComponentType().equals(type);
} else {
return f.getType().equals(type);
}
} catch (ClassNotFoundException e) {
System.out.println(String.format("Class '%s' cannot be loaded: %s", className, e.getMessage()));
}
}
assertTrue(detectedClassCount >= 2, "");
return false;
}), "No field " + propertyNameRegexp + " of type " + type.getName() + " (is array " + array + ") in class "
+ classDef.getName());
}
private void hasPropertyWithAnnotation(Class<?> classDef, String propertyNameRegexp, Class<?> annotation) {
List<Field> fields = Arrays.asList(classDef.getDeclaredFields());
assertTrue(
fields.stream().filter(f -> f.getName().matches(propertyNameRegexp))
.flatMap(f -> Arrays.asList(
f.getAnnotations()).stream()).map(a -> a.annotationType()).anyMatch(a ->
a.equals(annotation)),
"No field " + propertyNameRegexp + " with annotation " + annotation.getName() + " in class "
+ classDef.getName());
}
private void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
.anyMatch(m -> m.getReturnType().equals(returnType)),
"Method " + methodName + " not return " + returnType.getName());
}
private void hasMethod(Class<?> interfaceDef, String methodName, Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodName + " has no all parrams:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
private void hasMethodRegexp(Class<?> interfaceDef, String methodNameRegexp, Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().matches(methodNameRegexp)), "No method " + methodNameRegexp);
assertTrue(
methods.stream().filter(m -> m.getName().matches(methodNameRegexp))
.filter(m -> m.getReturnType().equals(returnType))
.anyMatch(m ->
Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodNameRegexp + " has no all parrams:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
private void hasMethod(Class<?> interfaceDef, boolean finalTag, boolean abstractTag, String methodName,
Class<?> returnType, Class<?>... params) {
List<Method> methods = Arrays.asList(interfaceDef.getDeclaredMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
assertTrue(
methods.stream().filter(m -> m.getName().contains(methodName))
.filter(m -> m.getReturnType().equals(returnType)
&& (Modifier.isAbstract(m.getModifiers()) == abstractTag)
&& (Modifier.isFinal(m.getModifiers()) == finalTag))
.anyMatch(m -> Arrays.asList(m.getParameterTypes()).containsAll(Arrays.asList(params))),
"Method " + methodName + " has no all params:"
+ Arrays.asList(params).stream().map(Class::getName).collect(Collectors.joining(", ")));
}
private void hasImplements(Class<?> clazz, String... interfaceNames) {
List<Class<?>> interfaces = new ArrayList<>();
Arrays.asList(interfaceNames).stream().map(name -> getClass(name)).forEach(c -> interfaces.add(c));
assertTrue(Arrays.asList(clazz.getInterfaces()).containsAll(interfaces), "Class not implements all interfaces:"
+ interfaces.stream().map(Class::getName).collect(Collectors.joining(", ")));
}
private void hasExtends(Class<?> clazz, String parentName) {
Class<?> parent = getClass(parentName);
assertTrue(clazz.getSuperclass().equals(parent),
"Class " + clazz.getName() + " not extends class " + parentName);
}
private void hasMethod(Class<?> interfaceDef, String methodName) {
List<Method> methods = Arrays.asList(interfaceDef.getMethods());
assertTrue(methods.stream().anyMatch(m -> m.getName().contains(methodName)), "No method " + methodName);
}
private Set<String> getNameOfAllClasses() {
......@@ -110,7 +204,10 @@ class ClassStructureTest {
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)));
allClasses.addAll(reflections.getAll(Scanners.SubTypes.filterResultsBy(c -> {
System.out.println(c);
return true;
})));
}
return allClasses;
}
......
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment