Skip to content
Snippets Groups Projects
GameController.java 3.76 KiB
	package lab;

import static java.util.Comparator.comparingInt;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.List;
import java.util.Random;
import java.util.Scanner;
import java.util.Set;

import javafx.animation.AnimationTimer;
import javafx.beans.value.ObservableValue;
import javafx.collections.FXCollections;
import javafx.fxml.FXML;
import javafx.scene.canvas.Canvas;
import javafx.scene.control.Label;
import javafx.scene.control.ListView;
import javafx.scene.control.Slider;
import javafx.scene.control.TextField;

public class GameController {

	private static final String FILE_NAME = "game-score.csv";

	private World world;
	
	@FXML
	private Slider angleSlider;
	
	@FXML
	private Slider strengthSlider;
	
	@FXML
	private Canvas canvas;
	
	@FXML
	private Label shoots;
	
	@FXML
	private Label hits;
	
	@FXML
	private TextField nameField;
	
	@FXML
	private ListView<Score> scoreList;
	
	private List<Score> highScores;
	
	
	private AnimationTimer animationTimer;

	private final Random rnd = new Random();
	
	
	public GameController() {
	}
	
	public void startGame() {
		scoreList.setItems(FXCollections.observableList(new ArrayList<>()));
		highScores = scoreList.getItems();
		this.world = new World(canvas.getWidth(), canvas.getHeight());
		this.world.setGameListener(new GameListenerImpl());
		//Draw scene on a separate thread to avoid blocking UI.
		animationTimer = new DrawingThread(canvas, world); 
		angleSlider.valueProperty().addListener(this::angleChanged);
		world.setCannonAngle(angleSlider.getValue());
		
		strengthSlider.valueProperty().addListener(this::strenghtChanged);
		world.setCannonStrength(strengthSlider.getValue());
		animationTimer.start();
	}


	public void stopGame() {
		animationTimer.stop();
	}
	
	
	@FXML
	private void firePressed() {
		world.fire();
	}
	
	@FXML
	private void gameOver() {
		int score = rnd.nextInt(11);
		String name = nameField.getText();
		highScores.add(new Score(name, score));
		//highScores.sort((o1, o2)->Integer.compare(o1.getScore(), o2.getScore()));
		highScores.sort(comparingInt(Score::getScore).reversed());
	}
	
	@FXML
	private void highScore() {
		Set<Score> tempSet = new LinkedHashSet<>();
		tempSet.addAll(highScores);
		highScores.clear();
		highScores.addAll(tempSet);
	}
	
	@FXML
	private void save() {
		try(PrintWriter pw = new PrintWriter(new FileWriter(FILE_NAME))) {
			for (Score score: highScores) {
				pw.printf("%s;%d\n", score.getName(), score.getScore());
			}
			
			/*
			Iterator<Score> iterator = highScores.iterator();
			while(iterator.hasNext()) {
				Score score = iterator.next();
				pw.printf("%s;%d\n", score.getName(), score.getScore());
				//iterator.remove();
			}*/
		} catch (IOException e) {
			e.printStackTrace();
		} 
	}
	
	@FXML
	private void load() {
		highScores.clear();
		try(Scanner scanner = new Scanner(new File(FILE_NAME)).useDelimiter(";\\n")) {
			while(scanner.hasNext()) {
				String name = scanner.next();
				int score = scanner.nextInt();
				highScores.add(new Score(name, score));
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
	
	private void angleChanged(ObservableValue<? extends Number> observable
								, Number oldValue, Number newValue) {
		world.setCannonAngle(newValue.doubleValue());
	}

	private void strenghtChanged(ObservableValue<? extends Number> observable
			, Number oldValue, Number newValue) {
		world.setCannonStrength(newValue.doubleValue());
	}
	
	private class GameListenerImpl implements GameListener {

		@Override
		public void stateChanged(int shoots, int hits) {
			GameController.this.shoots.setText("" + shoots);
			GameController.this.hits.setText("" + hits);
		}

		@Override
		public void gameOver() {
			stopGame();
		}
		
	}
}