Implement a console visual

This commit is contained in:
2020-07-20 11:14:18 +02:00
parent 61eeac50a1
commit 87a53149c9
11 changed files with 274 additions and 19 deletions

1
.gitignore vendored
View File

@@ -7,4 +7,5 @@ build/
# Logs # Logs
*.log *.log
*.log.*
*.log.lck *.log.lck

View File

@@ -9,9 +9,11 @@ import de.siphalor.was.content.product.ProductManager;
import de.siphalor.was.content.quest.Quest; import de.siphalor.was.content.quest.Quest;
import de.siphalor.was.content.quest.QuestGenerator; import de.siphalor.was.content.quest.QuestGenerator;
import de.siphalor.was.content.quest.QuestManager; import de.siphalor.was.content.quest.QuestManager;
import de.siphalor.was.content.quest.RandomQuestGenerator;
import de.siphalor.was.game.*; import de.siphalor.was.game.*;
import de.siphalor.was.util.Pair; import de.siphalor.was.util.Pair;
import de.siphalor.was.util.Util; import de.siphalor.was.util.Util;
import de.siphalor.was.visual.ConsoleVisual;
import de.siphalor.was.visual.JFXVisual; import de.siphalor.was.visual.JFXVisual;
import de.siphalor.was.visual.Visual; import de.siphalor.was.visual.Visual;
import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.NotNull;
@@ -58,7 +60,7 @@ public class WhatAStorage {
questManager = new QuestManager(); questManager = new QuestManager();
options = new Options(); options = new Options();
visual = new JFXVisual(); visual = new ConsoleVisual();
} }
public ContentManager getContentManager() { public ContentManager getContentManager() {
@@ -109,13 +111,13 @@ public class WhatAStorage {
} }
public void startGame() { public void startGame() {
questGenerator = questManager.get("example.test"); //questGenerator = questManager.get("example.test");
//questGenerator = new RandomQuestGenerator(); questGenerator = new RandomQuestGenerator();
quests.clear(); quests.clear();
storage = new Storage(GRID_SIZE, GRID_SIZE, GRID_SIZE); storage = new Storage(GRID_SIZE, GRID_SIZE, GRID_SIZE);
balance = new Balance(); balance = new Balance();
visual.onGameStart(); visual.onGameStart(GRID_SIZE, GRID_SIZE, GRID_SIZE);
if (options.getAutoRefillQuests()) { if (options.getAutoRefillQuests()) {
for (int i = 0; i < MAX_QUESTS; i++) { for (int i = 0; i < MAX_QUESTS; i++) {

View File

@@ -26,11 +26,15 @@ public class I18n extends ResourceBundle {
return DEFAULT_LANG; return DEFAULT_LANG;
} }
public void setLang(@NotNull String code, @NotNull ContentManager contentManager) { public boolean setLang(@NotNull String code, @NotNull ContentManager contentManager) {
if (lang == null || !lang.getCode().equals(code)) { if (lang == null || !lang.getCode().equals(code)) {
lang = new Lang(code); Lang l = new Lang(code);
lang.load(contentManager); if (l.load(contentManager)) {
lang = l;
return true;
}
} }
return false;
} }
public void reload(@NotNull ContentManager contentManager) { public void reload(@NotNull ContentManager contentManager) {

View File

@@ -24,7 +24,7 @@ public class Lang {
return code; return code;
} }
public void load(@NotNull ContentManager contentManager) { public boolean load(@NotNull ContentManager contentManager) {
properties.clear(); properties.clear();
contentManager.getAllOfResource("lang/" + code + ".properties").forEachOrdered(resource -> { contentManager.getAllOfResource("lang/" + code + ".properties").forEachOrdered(resource -> {
InputStream inputStream = resource.getInputStream(); InputStream inputStream = resource.getInputStream();
@@ -45,7 +45,9 @@ public class Lang {
if (properties.isEmpty()) { if (properties.isEmpty()) {
Util.LOGGER.log(Level.SEVERE, "Failed to load lang file for " + code); Util.LOGGER.log(Level.SEVERE, "Failed to load lang file for " + code);
return false;
} }
return true;
} }
@Nullable @Nullable

View File

@@ -0,0 +1,233 @@
package de.siphalor.was.visual;
import de.siphalor.was.WhatAStorage;
import de.siphalor.was.content.lang.I18n;
import de.siphalor.was.content.product.Product;
import de.siphalor.was.content.quest.Quest;
import de.siphalor.was.game.Balance;
import de.siphalor.was.game.Transaction;
import java.util.Arrays;
import java.util.Scanner;
import java.util.stream.Collectors;
public class ConsoleVisual implements Visual {
private final int CELL_WIDTH = 16;
private WhatAStorage was;
private Scanner scanner;
private State state;
private String[][][] storage;
private int budget;
private enum State {
MENU, GAME,
}
@Override
public void setup(WhatAStorage whatAStorage) {
state = State.MENU;
was = whatAStorage;
scanner = new Scanner(System.in);
}
@Override
public void run() {
loop:
while (true) {
String input = scanner.nextLine();
String[] parts = input.split(" ");
if (parts.length == 0) continue;
switch (state) {
case MENU:
switch (parts[0]) {
case "help": {
I18n i18n = I18n.getInstance();
System.out.println("start: " + i18n.getString("menu.start-game"));
System.out.println("exit: " + i18n.getString("game.quit"));
break;
}
case "start":
was.startGame();
break;
case "exit":
was.scheduleStop();
break loop;
default:
printInvalidInput();
break;
}
break;
case GAME:
switch (parts[0]) {
case "help": {
I18n i18n = I18n.getInstance();
System.out.println("status: " + i18n.getString("game.storage"));
System.out.println("budget: " + i18n.getString("game.budget"));
System.out.println("options: " + i18n.getString("menu.options"));
System.out.println("exit: " + i18n.getString("game.quit"));
break;
}
case "status": {
showGame();
System.out.println();
Balance balance = WhatAStorage.getInstance().getBalance();
showBudget(balance.getBudget(), balance.getTotalIncome(), balance.getTotalLoss());
break;
}
case "budget": {
Balance balance = WhatAStorage.getInstance().getBalance();
showBudget(balance.getBudget(), balance.getTotalIncome(), balance.getTotalLoss());
break;
}
case "exit":
was.scheduleStop();
break loop;
case "options":
if (parts.length == 1) {
System.out.println(I18n.getInstance().getString("menu.options.available"));
System.out.println("lang");
} else {
switch (parts[1]) {
case "lang":
if (parts.length == 2) {
System.out.println(Arrays.stream(WhatAStorage.getInstance().getLangs()).map(s ->
s + ": " + I18n.getInstance().getString("langs." + s)
).collect(Collectors.joining(", ")));
} else {
if (I18n.getInstance().setLang(parts[2], WhatAStorage.getInstance().getContentManager())) {
invalidateI18n();
WhatAStorage.getInstance().getOptions().save();
} else {
printInvalidInput();
}
}
break;
default:
printInvalidInput();
break;
}
}
break;
default:
printInvalidInput();
break;
}
break;
}
}
}
private void showGame() {
int width = storage.length;
int height = storage[0].length;
int depth = storage[0][0].length;
int index = 1;
final String empty = I18n.getInstance().getString("game.storage.empty");
for (int y = 0; y < height; y++) {
{
StringBuilder stringBuilder = new StringBuilder();
for (int x = 0; x < width; x++) {
stringBuilder.append(index);
stringBuilder.append(".");
stringBuilder.append(" ".repeat(CELL_WIDTH * (x + 1) + x * 3 - stringBuilder.length()));
if (x < width - 1) {
stringBuilder.append(" | ");
}
index++;
}
System.out.println(stringBuilder.toString());
}
for (int z = 0; z < depth; z++) {
StringBuilder stringBuilder = new StringBuilder();
for (int x = 0; x < width; x++) {
if (storage[x][y][z] != null) {
stringBuilder.append(I18n.getInstance().getString(storage[x][y][z]));
} else {
stringBuilder.append(empty);
}
stringBuilder.append(" ".repeat(CELL_WIDTH * (x + 1) + x * 3 - stringBuilder.length()));
if (x < width - 1) {
stringBuilder.append(" | ");
}
}
System.out.println(stringBuilder.toString());
}
if (y < height - 1) {
StringBuilder stringBuilder = new StringBuilder();
for (int x = 0; x < width; x++) {
stringBuilder.append("-".repeat(CELL_WIDTH));
if (x < width - 1) {
stringBuilder.append("-+-");
}
}
System.out.println(stringBuilder.toString());
}
}
}
private void showBudget(int budget, int totalIncome, int totalLoss) {
I18n i18n = I18n.getInstance();
System.out.println(i18n.format("game.budget.label", budget) +
" " +
i18n.format("game.balance.total-income", totalIncome) +
" " +
i18n.format("game.balance.total-loss", totalLoss));
}
private void printInvalidInput() {
System.out.println(I18n.getInstance().getString("general.invalid-input"));
}
@Override
public void onGameStart(int width, int height, int depth) {
storage = new String[width][height][depth];
state = State.GAME;
showGame();
System.out.println();
showBudget(0, 0, 0);
}
@Override
public void onScheduleStop() {
}
@Override
public void invalidateI18n() {
}
@Override
public void onBalanceChanged(int budget, Transaction transaction, int totalIncome, int totalLoss) {
}
@Override
public void onQuestAdded(Quest newQuest, boolean canCreateMore) {
}
@Override
public void onQuestRemoved(int index) {
}
@Override
public void onProductSet(int x, int y, int z, Product product) {
}
@Override
public void onProductCleared(int x, int y, int z, Product product) {
}
}

View File

@@ -44,6 +44,7 @@ public class JFXVisual extends Application implements Visual {
private static GameController gameController; private static GameController gameController;
private static GridPane storageGrid; private static GridPane storageGrid;
private static JFXStorageSlot[][] storageSlots; private static JFXStorageSlot[][] storageSlots;
private static int width, height, depth;
private static Scene optionsScene; private static Scene optionsScene;
private static OptionsController optionsController; private static OptionsController optionsController;
@@ -79,7 +80,11 @@ public class JFXVisual extends Application implements Visual {
} }
@Override @Override
public void onGameStart() { public void onGameStart(int width, int height, int depth) {
JFXVisual.width = width;
JFXVisual.height = height;
JFXVisual.depth = depth;
loadGameScene();
changeScene(gameScene); changeScene(gameScene);
} }
@@ -99,7 +104,7 @@ public class JFXVisual extends Application implements Visual {
public void onBalanceChanged(int budget, Transaction transaction, int totalIncome, int totalLoss) { public void onBalanceChanged(int budget, Transaction transaction, int totalIncome, int totalLoss) {
I18n i18n = I18n.getInstance(); I18n i18n = I18n.getInstance();
gameController.budgetLabel.setText(i18n.format("game.budget", budget)); gameController.budgetLabel.setText(i18n.format("game.budget.label", budget));
JFXUtil.setStyleClass(gameController.budgetLabel, "red", budget < 0); JFXUtil.setStyleClass(gameController.budgetLabel, "red", budget < 0);
if (balanceController != null) { if (balanceController != null) {
@@ -141,7 +146,6 @@ public class JFXVisual extends Application implements Visual {
primaryStage.setMinWidth(850); primaryStage.setMinWidth(850);
primaryStage.setMinHeight(500); primaryStage.setMinHeight(500);
loadGameScene();
loadOptionsScene(); loadOptionsScene();
primaryStage.setOnCloseRequest(event -> { primaryStage.setOnCloseRequest(event -> {
@@ -163,7 +167,7 @@ public class JFXVisual extends Application implements Visual {
gameScene = JFXUtil.loadScene("game", gameController, I18n.getInstance()); gameScene = JFXUtil.loadScene("game", gameController, I18n.getInstance());
prepareStorageGrid(3, 3, 3); prepareStorageGrid();
AssetsManager.getStream("textures/bin_closed.png").ifPresent(inputStream -> { AssetsManager.getStream("textures/bin_closed.png").ifPresent(inputStream -> {
gameController.trash.setImage(new Image(inputStream)); gameController.trash.setImage(new Image(inputStream));
@@ -262,7 +266,7 @@ public class JFXVisual extends Application implements Visual {
}); });
} }
private void prepareStorageGrid(int width, int height, int depth) { private void prepareStorageGrid() {
storageGrid = new GridPane(); storageGrid = new GridPane();
storageGrid.setId("storage-grid"); storageGrid.setId("storage-grid");
storageGrid.setPadding(new Insets(5D)); storageGrid.setPadding(new Insets(5D));

View File

@@ -8,7 +8,7 @@ import de.siphalor.was.game.Transaction;
public interface Visual { public interface Visual {
void setup(WhatAStorage whatAStorage); void setup(WhatAStorage whatAStorage);
void run(); void run();
void onGameStart(); void onGameStart(int width, int height, int depth);
void onScheduleStop(); void onScheduleStop();
void invalidateI18n(); void invalidateI18n();

View File

@@ -22,7 +22,7 @@
<ToolBar maxWidth="1.7976931348623157E308" prefHeight="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0"> <ToolBar maxWidth="1.7976931348623157E308" prefHeight="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
<items> <items>
<Button fx:id="balanceButton" mnemonicParsing="false" text="%game.balance" /> <Button fx:id="balanceButton" mnemonicParsing="false" text="%game.balance" />
<Label fx:id="budgetLabel" text="%game.budget"> <Label fx:id="budgetLabel" text="%game.budget.label">
<font> <font>
<Font size="19.0" /> <Font size="19.0" />
</font> </font>

View File

@@ -1,14 +1,18 @@
test.hello-world = Hallo Welt! test.hello-world = Hallo Welt!
menu.back = Zur\u00fcck menu.start-game = Spiel starten
menu.options = Optionen menu.options = Optionen
menu.options.available = Verf\u00fcgbare Optionen:
menu.options.back = Anwenden und zur\u00fcck menu.options.back = Anwenden und zur\u00fcck
menu.options.general = Allgemein menu.options.general = Allgemein
menu.options.gameplay = Spielmechanik menu.options.gameplay = Spielmechanik
menu.options.gameplay.quest-resolving = Erlauben Auftr\u00e4ge gegeneinander aufzul\u00f6sen menu.options.gameplay.quest-resolving = Erlauben Auftr\u00e4ge gegeneinander aufzul\u00f6sen
menu.options.gameplay.auto-quest-refill = Automatisch neue Auftr\u00e4ge akzeptieren menu.options.gameplay.auto-quest-refill = Automatisch neue Auftr\u00e4ge akzeptieren
game.budget = Budget: %d\u20ac general.invalid-input = Ung\u00fcltige Eingabe
game.budget = Budget
game.budget.label = Budget: %d\u20ac
game.budget.change.income = +%d\u20ac game.budget.change.income = +%d\u20ac
game.budget.change.loss = %d\u20ac game.budget.change.loss = %d\u20ac
game.quit = Spiel beenden game.quit = Spiel beenden

View File

@@ -3,14 +3,19 @@ test.hello-world = Hello World!
langs.en_us = English (America) langs.en_us = English (America)
langs.de_de = Deutsch langs.de_de = Deutsch
menu.start-game = Start game
menu.options = Options menu.options = Options
menu.options.available = Available options:
menu.options.back = Apply & Leave menu.options.back = Apply & Leave
menu.options.general = General menu.options.general = General
menu.options.gameplay = Gameplay menu.options.gameplay = Gameplay
menu.options.gameplay.quest-resolving = Allow quest resolving menu.options.gameplay.quest-resolving = Allow quest resolving
menu.options.gameplay.auto-quest-refill = Automatically refill quests menu.options.gameplay.auto-quest-refill = Automatically refill quests
game.budget = Budget: %d$ general.invalid-input = Invalid input
game.budget = Budget
game.budget.label = Budget: %d$
game.budget.change.income = +%d$ game.budget.change.income = +%d$
game.budget.change.loss = %d$ game.budget.change.loss = %d$
game.quit = Quit Game game.quit = Quit Game

View File

@@ -18,7 +18,7 @@ public class DummyVisual implements Visual {
} }
@Override @Override
public void onGameStart() { public void onGameStart(int width, int height, int depth) {
} }