From e2ea6a5f0350164041cec30d842820c0b111bdd4 Mon Sep 17 00:00:00 2001 From: zwu18 Date: Fri, 22 Sep 2017 02:40:54 +1200 Subject: [PATCH] Fixed issue with speedometer and sails interaction. #story[1311] --- .../Controllers/RaceViewController.java | 250 ++++++++++++++++-- 1 file changed, 228 insertions(+), 22 deletions(-) diff --git a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java index 6040c946..67233cd6 100644 --- a/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java +++ b/racevisionGame/src/main/java/visualiser/Controllers/RaceViewController.java @@ -1,6 +1,7 @@ package visualiser.Controllers; import com.interactivemesh.jfx.importer.stl.StlMeshImporter; +import com.sun.scenario.effect.impl.sw.sse.SSEBlend_SRC_OUTPeer; import eu.hansolo.medusa.*; import eu.hansolo.medusa.events.UpdateEvent; import javafx.animation.AnimationTimer; @@ -22,6 +23,7 @@ import javafx.scene.layout.StackPane; import javafx.scene.paint.Color; import javafx.scene.paint.Material; import javafx.scene.paint.PhongMaterial; +import javafx.scene.paint.Stop; import javafx.scene.shape.MeshView; import javafx.scene.shape.Shape3D; import javafx.scene.transform.Translate; @@ -211,25 +213,199 @@ public class RaceViewController extends Controller { * Create speedometer */ private void initialiseSpeedometer() { - gauge = GaugeBuilder.create().prefSize(200, 200).title("Speedometer").subTitle("Speed").unit("Knots").skinType(Gauge.SkinType.FLAT).build(); - gauge.setValueColor(Color.WHITE); - gauge.setTitleColor(Color.WHITE); - gauge.setSubTitleColor(Color.WHITE); - gauge.setBarColor(Color.WHITE); - gauge.setUnitColor(Color.WHITE); - gauge.setMaxValue(40); - fGauge = FGaugeBuilder.create() +// gauge = GaugeBuilder.create().prefSize(200, 200).title("Speedometer").subTitle("Speed").unit("Knots").skinType(Gauge.SkinType.FLAT).build(); +// gauge.setValueColor(Color.WHITE); +// gauge.setTitleColor(Color.WHITE); +// gauge.setSubTitleColor(Color.WHITE); +// gauge.setBarColor(Color.WHITE); +// gauge.setUnitColor(Color.WHITE); +// gauge.setMaxValue(40); +// fGauge = FGaugeBuilder.create() +// .prefSize(200, 200) +// .gauge(gauge) +// .gaugeDesign(GaugeDesign.METAL) +// .gaugeBackground(GaugeDesign.GaugeBackground.CARBON) +// .foregroundVisible(true) +// .build(); +// gauge.valueProperty().setValue(0); +// gauge.setAnimated(true); +// //fGauge.getGauge().valueProperty().setValue(0); +// //fGauge.getGauge().maxValueProperty().setValue(50); +// speedPane.getChildren().add(fGauge); + /** + * Definition of Sections that can be used for + * - Sections + * - Areas + * - TickMarkSections + * - TickLabelSections + * + * Sections will be checked against current value if gauge.getCheckSectionsForValue == true + */ + Section section1 = SectionBuilder.create() + .start(50) + .stop(75) + .color(Color.rgb(255, 200, 0, 0.7)) + .onSectionEntered(sectionEvent -> System.out.println("Entered Section 1")) + .onSectionLeft(sectionEvent -> System.out.println("Left Section 1")) + .build(); + + Section section2 = SectionBuilder.create() + .start(75) + .stop(100) + .color(Color.rgb(255, 0, 0, 0.7)) + .onSectionEntered(sectionEvent -> System.out.println("Entered Section 2")) + .onSectionLeft(sectionEvent -> System.out.println("Left Section 2")) + .build(); + + /** + * Definition of Markers + * You can attach a listener for the following event types + * - MARKER_PRESSED + * - MARKER_RELEASED + * - MARKER_EXCEEDED + * - MARKER_UNDERRUN + * via the MarkerBuilder + * To receive MARKER_EXCEEDED and MARKER_UNDERRUN events you have to check the + * current value against each marker by calling the markers checkForValue() method + */ + Marker marker1 = MarkerBuilder.create() + .value(25) + .text("Marker 1") + .color(Color.HOTPINK) + .markerType(Marker.MarkerType.DOT) + .onMarkerPressed(markerEvent -> System.out.println("Marker 1 pressed")) + .onMarkerReleased(markerEvent -> System.out.println("Marker 1 released")) + .build(); + + Marker marker2 = MarkerBuilder.create() + .value(75) + .text("Marker 2") + .color(Color.CYAN) + .markerType(Marker.MarkerType.STANDARD) + .onMarkerPressed(markerEvent -> System.out.println("Marker 2 pressed")) + .onMarkerReleased(markerEvent -> System.out.println("Marker 2 released")) + .build(); + + /** + * Create the Medusa Gauge with most of it's options + * Simply play with the boolean variables first to see what mean. + */ + gauge = GaugeBuilder.create() + .prefSize(200,200) // Set the preferred size of the control + // Related to Foreground Elements + .foregroundBaseColor(Color.WHITE) // Defines a color for title, subtitle, unit, value, tick label, tick mark, major tick mark, medium tick mark and minor tick mark + // Related to Title Text + .title("Title") // Set the text for the title + // Related to Sub Title Text + .subTitle("SubTitle") // Set the text for the subtitle + // Related to Unit Text + .unit("Unit") // Set the text for the unit + // Related to Value Text + .decimals(2) // Set the number of decimals for the value/lcd text + // Related to LCD + .lcdVisible(true) // Display a LCD instead of the plain value text + .lcdDesign(LcdDesign.STANDARD) // Set the design for the LCD + .lcdFont(LcdFont.DIGITAL_BOLD) // Set the font for the LCD (STANDARD, LCD, SLIM, DIGITAL_BOLD, ELEKTRA) + // Related to scale + .scaleDirection(Gauge.ScaleDirection.CLOCKWISE) // Define the direction of the Scale (CLOCKWISE, COUNTER_CLOCKWISE) + .minValue(0) // Set the start value of the scale + .maxValue(100) // Set the end value of the scale + .startAngle(320) // Set the start angle of your scale (bottom -> 0, direction -> CCW) + .angleRange(280) // Set the angle range of your scale starting from the start angle + // Related to Tick Labels + .tickLabelDecimals(0) // Set the number of decimals for the tick labels + .tickLabelLocation(TickLabelLocation.INSIDE) // Define wether the tick labels should be inside or outside the scale (INSIDE, OUTSIDE) + .tickLabelOrientation(TickLabelOrientation.ORTHOGONAL) // Define the orientation of the tick labels (ORTHOGONAL, HORIZONTAL, TANGENT) + .onlyFirstAndLastTickLabelVisible(false) // Define if only the first and last tick label should be visible + .tickLabelSectionsVisible(false) // Define if sections for tick labels should be visible + .tickLabelSections(section1, section2) // Define sections to color tick labels + .tickLabelColor(Color.BLACK) // Define the color for tick labels (overriden by tick label sections) + // Related to Tick Marks + .tickMarkSectionsVisible(false) // Define if sections for tick marks should be visible + .tickMarkSections(section1, section2) // Define sections to color tick marks + // Related to Major Tick Marks + .majorTickMarksVisible(true) // Define if major tick marks should be visible + .majorTickMarkType(TickMarkType.TRAPEZOID) // Define the tick mark type for major tick marks (LINE, DOT, TRAPEZOID, TICK_LABEL) + // Related to Medium Tick Marks + .mediumTickMarksVisible(false) // Define if medium tick marks should be visible + .mediumTickMarkType(TickMarkType.LINE) // Define the tick mark type for medium tick marks (LINE, DOT, TRAPEZOID) + // Related to Minor Tick Marks + .minorTickMarksVisible(true) // Define if minor tick marks should be visible + .minorTickMarkType(TickMarkType.LINE) // Define the tick mark type for minor tick marks (LINE, DOT, TRAPEZOID) + // Related to LED + .ledVisible(false) // Defines if the LED should be visible + .ledType(Gauge.LedType.STANDARD) // Defines the type of the LED (STANDARD, FLAT) + .ledColor(Color.rgb(255, 200, 0)) // Defines the color of the LED + .ledBlinking(false) // Defines if the LED should blink + // Related to Needle + .needleShape(Gauge.NeedleShape.ANGLED) // Defines the shape of the needle (ANGLED, ROUND, FLAT) + .needleSize(Gauge.NeedleSize.STANDARD) // Defines the size of the needle (THIN, STANDARD, THICK) + .needleColor(Color.CRIMSON) // Defines the color of the needle + // Related to Needle behavior + .startFromZero(false) // Defines if the needle should start from the 0 value + .returnToZero(false) // Defines if the needle should always return to the 0 value (only makes sense when animated==true) + // Related to Knob + .knobType(Gauge.KnobType.METAL) // Defines the type for the center knob (STANDARD, PLAIN, METAL, FLAT) + .knobColor(Color.LIGHTGRAY) // Defines the color that should be used for the center knob + .interactive(false) // Defines if it should be possible to press the center knob + .onButtonPressed(buttonEvent -> System.out.println("Knob pressed")) // Defines a handler that will be triggered when the center knob was pressed + .onButtonReleased(buttonEvent -> System.out.println("Knob released")) // Defines a handler that will be triggered when the center knob was released + // Related to Threshold + .thresholdVisible(true) // Defines if the threshold indicator should be visible + .threshold(50) // Defines the value for the threshold + .thresholdColor(Color.RED) // Defines the color for the threshold + .checkThreshold(true) // Defines if each value should be checked against the threshold + .onThresholdExceeded(thresholdEvent -> System.out.println("Threshold exceeded")) // Defines a handler that will be triggered if checkThreshold==true and the threshold is exceeded + .onThresholdUnderrun(thresholdEvent -> System.out.println("Threshold underrun")) // Defines a handler that will be triggered if checkThreshold==true and the threshold is underrun + // Related to Gradient Bar + .gradientBarEnabled(true) // Defines if a gradient filled bar should be visible to visualize a range + .gradientBarStops(new Stop(0.0, Color.BLUE),// Defines a conical color gradient that will be use to color the gradient bar + new Stop(0.25, Color.CYAN), + new Stop(0.5, Color.LIME), + new Stop(0.75, Color.YELLOW), + new Stop(1.0, Color.RED)) + // Related to Markers + .markersVisible(true) // Defines if markers will be visible + .markers(marker1, marker2) // Defines markers that will be drawn + // Related to Value + .animated(true) // Defines if the needle will be animated + .animationDuration(500) // Defines the speed of the needle in milliseconds (10 - 10000 ms) + .build(); + + /** + * Create a gauge with a frame and background that utilizes a Medusa gauge + * You can choose between the following GaugeDesigns + * - METAL + * - TILTED_GRAY + * - STEEL + * - BRASS + * - GOLD + * - BLACK_METAL + * - SHINY_METAL + * - ENZO + * - FLAT (when used one could set the frame color by calling GaugeDesign.FLAT.frameColor = Color.ORANGE;) + * - TRANSPARENT + * + * and the following GaugeBackgrounds + * - DARK_GRAY + * - BEIGE + * - ANTHRACITE + * - LIGHT_GRAY + * - WHITE + * - BLACK + * - CARBON + * - TRANSPARENT + */ + fGauge = FGaugeBuilder + .create() .prefSize(200, 200) .gauge(gauge) .gaugeDesign(GaugeDesign.METAL) .gaugeBackground(GaugeDesign.GaugeBackground.CARBON) .foregroundVisible(true) .build(); - gauge.valueProperty().setValue(0); - gauge.setAnimated(true); - //fGauge.getGauge().valueProperty().setValue(0); - //fGauge.getGauge().maxValueProperty().setValue(50); speedPane.getChildren().add(fGauge); + //(event -> gauge.setValue(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed())); } @@ -257,6 +433,7 @@ public class RaceViewController extends Controller { initialiseRaceClock(); initialiseSpeedometer(); raceTimer(); // start the timer + speedometerLoop(); new Sparkline(this.raceState, this.sparklineChart); timeZone.setText(this.raceState.getRaceClock().getTimeZone()); arrowController.setWindProperty(this.raceState.windProperty()); @@ -643,28 +820,57 @@ public class RaceViewController extends Controller { } } else { boatInfoTable.sort(); +// try { +// System.out.println(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed()); +// gauge.setValue(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed()); +// for (VisualiserBoat boat : boatInfoTable.getItems()){ +// if(raceState.getPlayerBoatID()==boat.getSourceID()){ +// gauge.setTitle("Position: " + (boatInfoTable.getItems().indexOf(boat)+1)); +// } +// } +// } catch (BoatNotFoundException e) { +// e.printStackTrace(); +// } + } + + //Return to main screen if we lose connection. + if (!visualiserRace.getServerConnection().isAlive()) { + try { + loadTitleScreen(); + } catch (Exception e) { + e.printStackTrace(); + } + //TODO we should display an error to the user + //TODO also need to "reset" any state (race, connections, etc...). + } + } + }.start(); + } + private void speedometerLoop(){ + new AnimationTimer(){ + @Override + public void handle(long arg0){ + if (raceState.getRaceStatusEnum() == RaceStatusEnum.FINISHED) { + stop(); // stop the timer + + } else { try { + System.out.println(gauge.getValue()); gauge.setValue(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed()); + fGauge.getGauge().setValue(raceState.getBoat(raceState.getPlayerBoatID()).getCurrentSpeed()); + Thread.sleep(50); for (VisualiserBoat boat : boatInfoTable.getItems()){ if(raceState.getPlayerBoatID()==boat.getSourceID()){ gauge.setTitle("Position: " + (boatInfoTable.getItems().indexOf(boat)+1)); + fGauge.getGauge().setTitle("Position: " + (boatInfoTable.getItems().indexOf(boat)+1)); } } } catch (BoatNotFoundException e) { e.printStackTrace(); - } - } - - //Return to main screen if we lose connection. - if (!visualiserRace.getServerConnection().isAlive()) { - try { - loadTitleScreen(); - } catch (Exception e) { + } catch (InterruptedException e) { e.printStackTrace(); } - //TODO we should display an error to the user - //TODO also need to "reset" any state (race, connections, etc...). } } }.start();