mirror of
https://github.com/michaelrausch/Party-Parrots-At-Sea.git
synced 2026-05-09 06:18:44 +00:00
Merge branch 'create-race-timer' into 'master'
Create race timer Created race timer controller #implement #test #story[16] See merge request !22
This commit is contained in:
@@ -1,9 +1,6 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import javafx.animation.AnimationTimer;
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.KeyValue;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.animation.*;
|
||||
import javafx.beans.property.DoubleProperty;
|
||||
import javafx.beans.property.SimpleDoubleProperty;
|
||||
import javafx.fxml.FXML;
|
||||
@@ -24,7 +21,6 @@ import seng302.models.mark.Mark;
|
||||
import seng302.models.mark.MarkType;
|
||||
import seng302.models.mark.SingleMark;
|
||||
import seng302.models.parsers.ConfigParser;
|
||||
import seng302.models.parsers.CourseParser;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
@@ -53,6 +49,13 @@ public class CanvasController {
|
||||
@FXML
|
||||
private Text windArrowText, windDirectionText;
|
||||
|
||||
@FXML Pane raceTimer;
|
||||
|
||||
private Animation.Status raceStatus = Animation.Status.PAUSED;
|
||||
|
||||
/**
|
||||
* Display the list of boats in the order they finished the race
|
||||
*/
|
||||
private void loadRaceResultView() {
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/FinishView.fxml"));
|
||||
loader.setController(new RaceResultController(race));
|
||||
@@ -69,6 +72,57 @@ public class CanvasController {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Load the race timer
|
||||
*/
|
||||
private void loadTimerView(){
|
||||
FXMLLoader loader = new FXMLLoader(getClass().getResource("/raceTimer.fxml"));
|
||||
loader.setController(new RaceTimerController(race));
|
||||
|
||||
try{
|
||||
raceTimer.getChildren().clear();
|
||||
raceTimer.getChildren().removeAll();
|
||||
raceTimer.getChildren().addAll((Pane) loader.load());
|
||||
}
|
||||
catch(javafx.fxml.LoadException e){
|
||||
System.out.println(e);
|
||||
}
|
||||
catch(IOException e){
|
||||
System.out.println(e);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Play each boats timeline
|
||||
*/
|
||||
private void playTimelines(){
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()){
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
|
||||
if (timeline.getStatus() == Animation.Status.PAUSED){
|
||||
timeline.play();
|
||||
}
|
||||
}
|
||||
raceStatus = Animation.Status.RUNNING;
|
||||
}
|
||||
|
||||
/**
|
||||
* Pause each boats timeline
|
||||
*/
|
||||
private void pauseTimelines(){
|
||||
for (TimelineInfo timelineInfo : timelineInfos.values()){
|
||||
Timeline timeline = timelineInfo.getTimeline();
|
||||
|
||||
if (timeline.getStatus() == Animation.Status.RUNNING){
|
||||
timeline.pause();
|
||||
}
|
||||
}
|
||||
raceStatus = Animation.Status.PAUSED;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the controller
|
||||
*/
|
||||
public void initialize() {
|
||||
gc = canvas.getGraphicsContext2D();
|
||||
gc.scale(15, 15);
|
||||
@@ -84,14 +138,26 @@ public class CanvasController {
|
||||
gc.clearRect(0, 0, 760, 360);
|
||||
drawCourse();
|
||||
drawBoats();
|
||||
|
||||
// If race has started, draw the boats and play the timeline
|
||||
if (race.getRaceTime() > 1){
|
||||
playTimelines();
|
||||
|
||||
}
|
||||
// Race has not started, pause the timelines
|
||||
else if (race.getRaceTime() < 1 || raceStatus == Animation.Status.RUNNING){
|
||||
pauseTimelines();
|
||||
}
|
||||
|
||||
}
|
||||
};
|
||||
|
||||
generateTimeline();
|
||||
|
||||
// starts the timer and reads events from each boat's time line
|
||||
timer.start();
|
||||
|
||||
loadTimerView();
|
||||
|
||||
Double maxDuration = 0.0;
|
||||
Timeline maxTimeline = null;
|
||||
|
||||
@@ -105,10 +171,16 @@ public class CanvasController {
|
||||
maxTimeline = timeline;
|
||||
}
|
||||
|
||||
// Timelines are paused by default
|
||||
timeline.play();
|
||||
timeline.pause();
|
||||
raceStatus = Animation.Status.RUNNING;
|
||||
}
|
||||
|
||||
maxTimeline.setOnFinished(event -> loadRaceResultView());
|
||||
maxTimeline.setOnFinished(event -> {
|
||||
race.setRaceFinished();
|
||||
loadRaceResultView();
|
||||
});
|
||||
|
||||
//set wind direction!!!!!!! can't find another place to put my code --haoming
|
||||
double windDirection = new ConfigParser("doc/examples/config.xml").getWindDirection();
|
||||
|
||||
@@ -0,0 +1,78 @@
|
||||
package seng302.controllers;
|
||||
|
||||
import javafx.animation.KeyFrame;
|
||||
import javafx.animation.Timeline;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.fxml.Initializable;
|
||||
import javafx.scene.text.Text;
|
||||
import javafx.util.Duration;
|
||||
import seng302.models.Race;
|
||||
|
||||
import java.net.URL;
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public class RaceTimerController implements Initializable{
|
||||
private Timeline timeline;
|
||||
private Race race;
|
||||
|
||||
@FXML
|
||||
private Text timerLabel;
|
||||
|
||||
/**
|
||||
* Convert seconds to a string of the format mm:ss
|
||||
* @param time the time in seconds
|
||||
* @return a formatted string
|
||||
*/
|
||||
public String convertTimeToMinutesSeconds(int time){
|
||||
if (time < 0){
|
||||
return String.format("-%02d:%02d", (time * -1) / 60, (time * -1)% 60);
|
||||
}
|
||||
return String.format("%02d:%02d", time / 60, time % 60);
|
||||
}
|
||||
|
||||
/**
|
||||
* Controller to control the race timer
|
||||
* @param race the race the timer is timing
|
||||
*/
|
||||
public RaceTimerController(Race race){
|
||||
this.race = race;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void initialize(URL location, ResourceBundle resources) {
|
||||
timeline = new Timeline();
|
||||
timeline.setCycleCount(Timeline.INDEFINITE);
|
||||
|
||||
// Run timer update every second
|
||||
timeline.getKeyFrames().add(
|
||||
new KeyFrame(Duration.seconds(1),
|
||||
event -> {
|
||||
// Stop timer if race is finished
|
||||
if (this.race.isRaceFinished()){
|
||||
this.timeline.stop();
|
||||
}
|
||||
else{
|
||||
timerLabel.setText(convertTimeToMinutesSeconds(race.getRaceTime()));
|
||||
this.race.incrementRaceTime();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
// Start the timer
|
||||
timeline.playFromStart();
|
||||
}
|
||||
|
||||
/**
|
||||
* Stop the race timer
|
||||
*/
|
||||
public void stop(){
|
||||
timeline.stop();
|
||||
}
|
||||
|
||||
/**
|
||||
* Start the race timer
|
||||
*/
|
||||
public void start(){
|
||||
timeline.play();
|
||||
}
|
||||
}
|
||||
@@ -15,6 +15,8 @@ public class Race {
|
||||
private List<Mark> course; // Marks in the race
|
||||
private long startTime = 0;
|
||||
private double timeScale = 1;
|
||||
private boolean raceFinished = false; // Race is finished
|
||||
private int raceTime = -10; // Current time in the race
|
||||
|
||||
/**
|
||||
* Race class containing the boats and legs in the race
|
||||
@@ -106,7 +108,6 @@ public class Race {
|
||||
else{
|
||||
Event event = new Event(time, boat, course.get(i));
|
||||
events.get(boat).add(event);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -122,20 +123,74 @@ public class Race {
|
||||
generateEvents();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race course
|
||||
* @param course a list of marks in the course
|
||||
*/
|
||||
public void addCourse(List<Mark> course) {
|
||||
this.course = course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a list of marks in the course
|
||||
* @return
|
||||
*/
|
||||
public List<Mark> getCourse() {
|
||||
return course;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a map of the events in the race
|
||||
* @return
|
||||
*/
|
||||
public HashMap<Boat, List> getEvents() {
|
||||
return events;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set a boat as finished
|
||||
* @param boat The boat that has finished the race
|
||||
*/
|
||||
public void setBoatFinished(Boat boat){
|
||||
System.out.println(boat.getTeamName() + " finished");
|
||||
this.finishingOrder.add(boat);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race as finished
|
||||
*/
|
||||
public void setRaceFinished(){
|
||||
this.raceFinished = true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return whether or not the race is finished
|
||||
* @return true if the race is finished
|
||||
*/
|
||||
public boolean isRaceFinished(){
|
||||
return this.raceFinished;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the race time
|
||||
* @param raceTime the race time in seconds
|
||||
*/
|
||||
public void setRaceTime(int raceTime){
|
||||
this.raceTime = raceTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the race time
|
||||
* @return the race time in seconds
|
||||
*/
|
||||
public int getRaceTime(){
|
||||
return this.raceTime;
|
||||
}
|
||||
|
||||
/**
|
||||
* Increment the race time by one second
|
||||
*/
|
||||
public void incrementRaceTime(){
|
||||
this.raceTime ++;
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@
|
||||
<Font name="System Bold" size="13.0" />
|
||||
</font>
|
||||
</Text>
|
||||
<Pane fx:id="raceTimer" layoutX="11.0" layoutY="30.0" prefHeight="51.0" prefWidth="193.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
</children>
|
||||
|
||||
@@ -0,0 +1,15 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.text.*?>
|
||||
<?import java.lang.*?>
|
||||
<?import javafx.scene.layout.*?>
|
||||
|
||||
<Pane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="66.0" prefWidth="181.0" xmlns="http://javafx.com/javafx/8" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<Text fx:id="timerLabel" layoutY="41.0" strokeType="OUTSIDE" strokeWidth="0.0" text="00:00" textAlignment="CENTER" wrappingWidth="181.0">
|
||||
<font>
|
||||
<Font size="34.0" />
|
||||
</font>
|
||||
</Text>
|
||||
</children>
|
||||
</Pane>
|
||||
@@ -0,0 +1,26 @@
|
||||
package seng302;
|
||||
|
||||
import org.junit.Test;
|
||||
import seng302.controllers.RaceTimerController;
|
||||
import seng302.models.Race;
|
||||
|
||||
import static org.junit.Assert.assertTrue;
|
||||
|
||||
|
||||
public class TestRaceTimer {
|
||||
@Test
|
||||
public void testPositiveTimeString(){
|
||||
RaceTimerController controller = new RaceTimerController(new Race());
|
||||
String result = controller.convertTimeToMinutesSeconds(61);
|
||||
|
||||
assertTrue(result.equals("01:01"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testNegativeTimeString(){
|
||||
RaceTimerController controller = new RaceTimerController(new Race());
|
||||
String result = controller.convertTimeToMinutesSeconds(-61);
|
||||
|
||||
assertTrue(result.equals("-01:01"));
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user