forked from MiramarCISC/CISC190-Project-Template
-
Notifications
You must be signed in to change notification settings - Fork 3
Expand file tree
/
Copy pathMain.java
More file actions
232 lines (207 loc) · 8.09 KB
/
Main.java
File metadata and controls
232 lines (207 loc) · 8.09 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
package edu.sdccd.cisc190;
import javafx.application.Application;
import javafx.application.Platform;
import javafx.scene.Scene;
import javafx.scene.control.*;
import javafx.scene.layout.VBox;
import javafx.stage.Stage;
import java.util.Collections; //add import statement for shuffling
import java.util.List;
import java.util.concurrent.Executors;
import java.util.concurrent.ScheduledExecutorService;
import java.util.concurrent.TimeUnit;
/**
* The Main class serves as the entry point for the Quiz Game application.
* <p>
* This JavaFX-based application provides an interactive quiz game with a countdown timer.
* It initializes the user interface, manages game logic, and handles user interactions.
* </p>
*/
public class Main extends Application {
private QuizGame quizGame;
private Label questionLabel;
private Label timerLabel;
private Label scoreLabel;
private VBox optionsBox;
private int currentQuestionIndex = 0;
private static final int TIMER_DURATION = 300;
private int timeLeft = TIMER_DURATION; // Timer duration in seconds (5 minutes)
private int score = 0; //score tracking
private ScheduledExecutorService timerExecutor;
private boolean isPaused = false; // Track if the game is paused
private Button pauseButton; // Button to toggle pause/resume
/**
* The main method that launches the JavaFX application.
*
* @param args command-line arguments (not used).
*/
public static void main(String[] args) {
launch(args);
}
/**
* Sets up the initial welcome screen and displays the start button.
*
* @param primaryStage the primary stage for the application.
*/
@Override
public void start(Stage primaryStage) {
Label banner = new Label("Welcome to the Quiz Game!");
banner.setStyle("-fx-font-size: 24px; -fx-font-weight: bold;");
Button startButton = new Button("Start Game");
startButton.setStyle("-fx-font-size: 18px;");
startButton.setOnAction(e -> showGameScreen(primaryStage));
VBox welcomeLayout = new VBox(20, banner, startButton);
welcomeLayout.setPrefSize(400, 300);
welcomeLayout.setStyle("-fx-alignment: center;");
primaryStage.setTitle("Quiz Game");
primaryStage.setScene(new Scene(welcomeLayout));
primaryStage.show();
}
//TODO: You could possibly add somewhere in here sound effects for getting a right/wrong answer.
/**
* Transitions to the game screen, initializes the quiz game, and loads questions.
*
* @param primaryStage the primary stage for the application.
*/
private void showGameScreen(Stage primaryStage) {
quizGame = new QuizGame("Quiz Game");
try {
quizGame.loadQuestions("src/main/resources/questions.txt");
} catch (Exception e) {
showError("Error loading questions: " + e.getMessage());
e.printStackTrace();
return;
}
//Randomize the order of questions
Collections.shuffle(quizGame.getQuestions()); //shuffle the questions
questionLabel = new Label();
questionLabel.setWrapText(true);
questionLabel.setStyle("-fx-font-size: 24px; -fx-font-weight: bold; -fx-text-alignment: center;");
timerLabel = new Label("Time left: " + timeLeft + " seconds");
timerLabel.setStyle("-fx-font-size: 16px;");
scoreLabel = new Label("Score: " + score); // intialize score label
scoreLabel.setStyle("-fx-font-size: 16px; -fx-font-weight: bold;");
optionsBox = new VBox(15);
// Create Pause Button
pauseButton = new Button("Pause Timer");
pauseButton.setStyle("-fx-font-size: 16px;");
pauseButton.setOnAction(e -> togglePause()); // Set action for pause/resume
VBox gameLayout = new VBox(30, questionLabel, optionsBox, scoreLabel, timerLabel, pauseButton);
gameLayout.setPrefSize(800, 800); //adjusted for larger window size
gameLayout.setStyle("-fx-padding: 30; -fx-alignment: top-center; -fx-spacing: 20;");
primaryStage.setScene(new Scene(gameLayout));
primaryStage.show();
startGame();
}
/**
* Starts the quiz game by displaying the first question and initializing the timer.
*/
public void startGame() {
quizGame.startGame();
showQuestion();
startTimer();
}
/**
* Displays the current question and its answer options.
* <p>
* Handles both multiple-choice and true/false questions.
* Ends the game if there are no more questions.
* </p>
*/
private void showQuestion() {
if (currentQuestionIndex >= quizGame.getQuestions().size()) {
endGame();
return;
}
Question question = quizGame.getQuestions().get(currentQuestionIndex);
questionLabel.setText(question.getQuestionText());
optionsBox.getChildren().clear();
if (question instanceof MultipleChoiceQuestion mcQuestion) {
for (String choice : mcQuestion.getChoices()) {
Button choiceButton = new Button(choice);
choiceButton.setOnAction(e -> handleAnswer(choice));
optionsBox.getChildren().add(choiceButton);
}
} else if (question instanceof TrueFalseQuestion) {
Button trueButton = new Button("True");
trueButton.setOnAction(e -> handleAnswer("True"));
Button falseButton = new Button("False");
falseButton.setOnAction(e -> handleAnswer("False"));
optionsBox.getChildren().addAll(trueButton, falseButton);
}
}
/**
* Handles the user's answer selection.
* <p>
* Validates the answer, updates the score if correct, and moves to the next question.
* </p>
*
* @param answer the answer selected by the user.
*/
private void handleAnswer(String answer) {
Question question = quizGame.getQuestions().get(currentQuestionIndex);
if (question.checkAnswer(answer)) {
quizGame.incrementScore();
score++; //
scoreLabel.setText("Score: " + score); // update score label after each correct answer
}
currentQuestionIndex++;
showQuestion();
}
/**
* Starts the countdown timer for the quiz.
* <p>
* Updates the timer label every second and ends the game when the timer reaches zero.
* </p>
*/
public void startTimer() {
timerExecutor = Executors.newSingleThreadScheduledExecutor();
timerExecutor.scheduleAtFixedRate(() -> {
if (timeLeft > 0 && !isPaused) { //check if game is not paused
timeLeft--;
Platform.runLater(() -> timerLabel.setText("Time left: " + timeLeft + " seconds"));
} else {
timerExecutor.shutdown();
Platform.runLater(this::endGame);
}
}, 0, 1, TimeUnit.SECONDS);
}
/** Pauses/resumes timer
*
*/
private void togglePause() {
isPaused = !isPaused; // Toggle the pause
if (isPaused) {
pauseButton.setText("Resume Timer"); //Change button text when paused
} else {
pauseButton.setText("Pause Timer"); //Change button text when resumed
}
}
/**
* Ends the quiz game and displays the final score.
* <p>
* Saves the high score and terminates the application.
* </p>
*/
public void endGame() {
quizGame.endGame();
timerExecutor.shutdown();
Alert alert = new Alert(Alert.AlertType.INFORMATION,"Game Over! Your Score: " + quizGame.getScore());
alert.showAndWait();
try {
quizGame.saveHighScore(quizGame.getScore());
} catch (Exception e) {
showError("Error saving high score: " + e.getMessage());
}
System.exit(0);
}
/**
* Displays an error message in an alert dialog.
*
* @param message the error message to display.
*/
private void showError(String message) {
Alert alert = new Alert(Alert.AlertType.ERROR, message);
alert.showAndWait();
}
}