JavaFX обновляет текущее местоположение с помощью setOnKeyPressed - PullRequest
2 голосов
/ 06 января 2020

Я сейчас изучаю JavaFX, и я решил сделать простую приключенческую игру. Описание местоположения с доступными выходами отображается в текстовой области и в текстовом поле пользователь вводит, в каком направлении он хочет go. Однако я столкнулся с проблемой: после выбора направления я должен снова нажать клавишу ввода, чтобы правильно обновить текущее местоположение и доступные выходы. Мне удалось обнаружить, что в текущей версии это связано с тем, как я обновляю переменную "lo c", которая отвечает за описание текущего местоположения. Я понятия не имею, как я могу это исправить, или как я должен изменить способ, которым он работает. Может ли кто-нибудь помочь мне с этим? Заранее благодарю за помощь

Класс местоположения:

package sample.LocationsSystem;

import java.util.HashMap;
import java.util.Map;

public class Location {
private final int locationID;
private final String description;
private final Map<String, Integer> exits;

public Location(int locationID, String description) {
    this.locationID = locationID;
    this.description = description;
    this.exits = new HashMap<>();
}

public void addExit(String direction, int location) {
    exits.put(direction, location);
}

public int getLocationID() {
    return locationID;
}

public String getDescription() {
    return description;
}

public Map<String, Integer> getExits() {
    return new HashMap<String, Integer>(exits);
}
}

Места с описаниями и выходами:

package sample.LocationsSystem;

import java.util.HashMap;
import java.util.Map;

public class Locations {

private static Map<Integer, Location> locationsMap = new HashMap<>();

public Locations() {
    initializeMap();
}

public static Map<Integer, Location> getLocationsMap() {
    return locationsMap;
}

public static void initializeMap(){
    locationsMap.put(0, new Location(0,"You entered the dungeon"));
    locationsMap.put(1, new Location(1,"You are in a narrow corridor"));
    locationsMap.put(2, new Location(2,"You are in round basement. You can see many doors around you"));
    locationsMap.put(3, new Location(3,"You are in a dark corridor. Strange noises are coming from the door just before you"));
    locationsMap.put(4, new Location(4,"Location 4"));
    locationsMap.put(5, new Location(5,"It's nothing here. Turn back"));
    locationsMap.put(6, new Location(6,"It's a broom cupboard."));
    locationsMap.put(7, new Location(7,"It's just a corridor"));
    locationsMap.put(8, new Location(8,"You entered into old throne room"));
    locationsMap.put(9, new Location(9,"It looks like an old armory"));
    locationsMap.put(10, new Location(10,"You can see a large pile of gold coins. That's what you came here for."));


    locationsMap.get(0).addExit("W",1);

    locationsMap.get(1).addExit("N",2);
    locationsMap.get(1).addExit("E",0);

    locationsMap.get(2).addExit("N",6);
    locationsMap.get(2).addExit("S",1);
    locationsMap.get(2).addExit("E",3);
    locationsMap.get(2).addExit("W",5);

    locationsMap.get(5).addExit("E",2);

    locationsMap.get(6).addExit("S",2);

    locationsMap.get(3).addExit("E",4);
    locationsMap.get(3).addExit("W",2);

    locationsMap.get(4).addExit("N",7);
    locationsMap.get(4).addExit("W",3);

    locationsMap.get(7).addExit("S",4);
    locationsMap.get(7).addExit("E",8);

    locationsMap.get(8).addExit("N",10);
    locationsMap.get(8).addExit("S",9);
    locationsMap.get(8).addExit("W",7);

    locationsMap.get(9).addExit("N",8);


    Map<String, String> vocabulary = new HashMap<String, String>();
    vocabulary.put("NORTH", "N");
    vocabulary.put("SOUTH", "S");
    vocabulary.put("WEST", "W");
    vocabulary.put("EAST", "E");
}
}

И мой класс контроллера:

package sample;

import javafx.fxml.FXML;
import javafx.scene.control.TextArea;
import javafx.scene.control.TextField;
import javafx.scene.input.KeyCode;
import sample.Characters.Player;
import sample.FightSystem.Fight;
import sample.LocationsSystem.Locations;

import java.util.Map;


public class Controller {

@FXML
TextField HPTextField;

@FXML
TextField enemyHP;

@FXML
TextField potionsTextField;

@FXML
TextField textField;

@FXML
TextArea mainTextArea;

public void clearTextField() {
    textField.clear();
}

int loc = 0;
public void initialize() {

    Player player = new Player("Player", 100, 10);
    Fight fight = new Fight();

    HPTextField.setText(Integer.toString(player.getHp()));
    potionsTextField.setText(Integer.toString(player.getPotions().size()));

    mainTextArea.setText("Welcome to adventure game! \n=======PRESS ENTER TO START======");

    Locations locations = new Locations();
    Map<String, Integer> exits = locations.getLocationsMap().get(loc).getExits();

    textField.setOnKeyPressed(keyEvent -> {
        if (keyEvent.getCode().equals(KeyCode.ENTER)) {

            String direction = textField.getText().toUpperCase();

            mainTextArea.appendText(locations.getLocationsMap().get(loc).getDescription()
                    + "\n In which direction would you like to go? \nAvailable directions: ");

            for (String exit : exits.keySet()) {
                mainTextArea.appendText(exit + " ");
            }

            if (exits.containsKey(direction)) {
                loc = exits.get(direction);
            }
            textField.clear();
        }
    });
}
}

1 Ответ

2 голосов
/ 07 января 2020

Вот пример, предназначенный, чтобы дать вам представление о том, как вы можете продолжить это и решить проблему настройки местоположения, которая у вас есть в настоящее время.

Что делает образец, так это перемещается в начальное местоположение, а затем каждый раз, когда пользователь перемещается в новое местоположение, обновляет местоположение с соответствующей обратной связью с пользователем в предоставленной текстовой области.

Ключевым отличием вашего вопроса является то, что следующий код немедленно обновит ссылку на текущее местоположение и предоставит обратную связь при перемещении в новое местоположение, как только это перемещение будет выполнено, а не в следующий раз. нажата клавиша.

private static final int STARTING_LOC = 0;
private Locations locations = new Locations();
private int loc;

private TextArea mainTextArea = new TextArea();
private TextField textField = new TextField();

public void initialize() {
    mainTextArea.setText("Welcome to adventure game!");
    moveTo(STARTING_LOC);

    textField.setOnKeyPressed(keyEvent -> {
        if (keyEvent.getCode().equals(KeyCode.ENTER)) {
            String direction = textField.getText().toUpperCase();
            Integer newLoc = getCurrentExits().get(direction);
            if (newLoc != null) {
                moveTo(newLoc);
            }

            textField.setText("");
        }
    });
}

private void moveTo(int newLoc) {
    this.loc = newLoc;
    mainTextArea.appendText(
        locations.getLocationsMap().get(loc).getDescription()
            + "\n In which direction would you like to go? \nAvailable directions: "
    );
    for (String exit : getCurrentExits().keySet()) {
        mainTextArea.appendText(exit + " ");
    }
}

private Map<String, Integer> getCurrentExits() {
    return locations.getLocationsMap().get(loc).getExits();
}

Пример основан на коде из вашего вопроса, поэтому часть кода, необходимого для его компиляции, содержится в вашем вопросе, а не в этом ответе. Этот пример не предназначен для демонстрации наилучшей практики создания приключенческой игры. Это всего лишь короткий фрагмент, а не полная программа, и не ie в F XML. Предполагается также, что методы stati c вашего класса Locations заменяются методами non-stati c.

Не связанный совет

Несколько вещей, которые вы могли бы Подумайте о том, чтобы поступить иначе:

  1. Используйте перечислимые типы в зависимости от ситуации, например, перечислимый тип Direction вместо HashMap.
  2. Сохраните данные о вашем местоположении в файл JSON, читайте, используя Jackson . Реляционная база данных также может быть рассмотрена, но с JSON, вероятно, будет легче работать, если вы не столкнетесь с гораздо более сложными требованиями.
  3. Назовите места с удобочитаемыми именами и обращайтесь к выходам, используя те же имена, а не целые числа.
  4. Используйте ссылки на объекты местоположения, а не индексированное значение int ID. Например, getCurrentExits может возвращать Map<Direction, Location>, а не Map<String, Integer>, поэтому у вас есть более типичная типизированная информация в ваших структурах данных.
  5. Абстрагируйте основной движок игры от пользовательского интерфейса, чтобы его можно было разрабатывать и тестировать независимо от пользовательского интерфейса, затем вставьте экземпляры модели игрового движка и вызовы экземпляров службы в интерфейс пользовательского интерфейса по мере необходимости.

То, что у вас есть в настоящее время, хорошо для начала, вам не нужно реализовывать какие-либо из предлагаемые идеи (и они могут потенциально сделать ваше приложение более сложным, а не менее сложным, чего вы, вероятно, избегаете на данном этапе), это всего лишь некоторые вещи, которые мне приходили в голову, когда я смотрел на ваш код, если вы хотели разработать приложение в нечто значительно большее или более сложное.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...