A huge amount of work on GUI and Gameplay
This commit is contained in:
@@ -4,13 +4,18 @@ import de.siphalor.was.content.ContentManager;
|
||||
import de.siphalor.was.content.lang.I18n;
|
||||
import de.siphalor.was.content.pack.FileContentPack;
|
||||
import de.siphalor.was.content.pack.JarContentPack;
|
||||
import de.siphalor.was.content.product.Product;
|
||||
import de.siphalor.was.content.product.ProductManager;
|
||||
import de.siphalor.was.content.quest.Quest;
|
||||
import de.siphalor.was.content.quest.QuestGenerator;
|
||||
import de.siphalor.was.content.quest.QuestManager;
|
||||
import de.siphalor.was.game.Balance;
|
||||
import de.siphalor.was.game.Storage;
|
||||
import de.siphalor.was.visual.JFXVisual;
|
||||
import de.siphalor.was.visual.Visual;
|
||||
import org.jetbrains.annotations.Contract;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.io.File;
|
||||
import java.nio.file.Path;
|
||||
@@ -19,6 +24,7 @@ import java.util.List;
|
||||
|
||||
public class WhatAStorage {
|
||||
private static final int MAX_QUESTS = 3;
|
||||
private static final int GRID_SIZE = 3;
|
||||
|
||||
public static final String TITLE = "What a Storage";
|
||||
private static final WhatAStorage INSTANCE = new WhatAStorage();
|
||||
@@ -39,6 +45,7 @@ public class WhatAStorage {
|
||||
private Balance balance;
|
||||
private QuestGenerator questGenerator;
|
||||
private final List<Quest> quests = new ArrayList<>(MAX_QUESTS);
|
||||
private Storage storage;
|
||||
|
||||
private WhatAStorage() {
|
||||
contentManager = new ContentManager();
|
||||
@@ -94,6 +101,7 @@ public class WhatAStorage {
|
||||
public void loadGame() {
|
||||
questGenerator = questManager.get("normal");
|
||||
quests.clear();
|
||||
storage = new Storage(GRID_SIZE, GRID_SIZE, GRID_SIZE);
|
||||
balance = new Balance();
|
||||
}
|
||||
|
||||
@@ -138,6 +146,75 @@ public class WhatAStorage {
|
||||
Quest quest = quests.remove(index);
|
||||
addTransaction(Balance.Transaction.ABANDON, -quest.getReward());
|
||||
|
||||
visual.onQuestAbandoned(index);
|
||||
visual.onQuestRemoved(index);
|
||||
}
|
||||
|
||||
public boolean canStoreProduct(@Nullable Product product, int x, int y) {
|
||||
return product != null && storage.get(x, y).fits(product) && product.testY(y);
|
||||
}
|
||||
|
||||
public boolean canStoreProduct(int questIndex, int x, int y) {
|
||||
return canStoreProduct(quests.get(questIndex).getProduct(), x, y);
|
||||
}
|
||||
|
||||
public boolean canMoveProduct(int x1, int y1, int x2, int y2) {
|
||||
return canStoreProduct(storage.get(x1, y1).front(), x2, y2);
|
||||
}
|
||||
|
||||
public void storeProduct(int questIndex, int x, int y) {
|
||||
Quest quest = quests.get(questIndex);
|
||||
if (quest != null && quest.getType() == Quest.Type.IN) {
|
||||
Product product = quest.getProduct();
|
||||
|
||||
int z = storage.get(x, y).add(product);
|
||||
if (z >= 0 && product.testY(y)) {
|
||||
quests.remove(questIndex);
|
||||
addTransaction(Balance.Transaction.STORE, quest.getReward());
|
||||
visual.onQuestRemoved(questIndex);
|
||||
visual.onProductSet(x, y, z, quest.getProduct());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public boolean canSellProduct(int questIndex, int x, int y) {
|
||||
Quest quest = quests.get(questIndex);
|
||||
if (quest != null && quest.getType() == Quest.Type.OUT) {
|
||||
return quest.getProduct().equals(storage.get(x, y).front());
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public boolean sellProduct(int questIndex, int x, int y) {
|
||||
if (canSellProduct(questIndex, x, y)) {
|
||||
int z = storage.get(x, y).pop();
|
||||
addTransaction(Balance.Transaction.SELL, quests.get(questIndex).getReward());
|
||||
quests.remove(questIndex);
|
||||
visual.onQuestRemoved(questIndex);
|
||||
visual.onProductCleared(x, y, z);
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
public void moveProduct(int x1, int y1, int x2, int y2) {
|
||||
Product product = storage.get(x1, y1).front();
|
||||
if (product != null && product.testY(y2)) {
|
||||
int z2 = storage.get(x2, y2).add(product);
|
||||
if (z2 >= 0) {
|
||||
int z1 = storage.get(x1, y1).pop();
|
||||
|
||||
addTransaction(Balance.Transaction.MOVE, -100);
|
||||
visual.onProductCleared(x1, y1, z1);
|
||||
visual.onProductSet(x2, y2, z2, product);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void destroyProduct(int x, int y) {
|
||||
int z = storage.get(x, y).pop();
|
||||
if (z >= 0) {
|
||||
addTransaction(Balance.Transaction.DESTROY, -500);
|
||||
visual.onProductCleared(x, y, z);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,10 +13,6 @@ import java.util.Map;
|
||||
import java.util.Optional;
|
||||
|
||||
public class AssetsManager {
|
||||
private static final Map<String, Image> imageCache = new HashMap<>();
|
||||
|
||||
@NotNull
|
||||
public static final Image MISSINGNO = getImage("textures/missingno.png");
|
||||
|
||||
@NotNull
|
||||
public static Optional<InputStream> getStream(@NotNull String path) {
|
||||
@@ -28,20 +24,4 @@ public class AssetsManager {
|
||||
return Optional.ofNullable(Thread.currentThread().getContextClassLoader().getResource(path));
|
||||
}
|
||||
|
||||
@NotNull
|
||||
public static Image getImage(@NotNull String path) {
|
||||
Image image = imageCache.get(path);
|
||||
if (image == null) {
|
||||
image = getStream(path).map(inputStream -> {
|
||||
try {
|
||||
return (Image) ImageIO.read(inputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}).orElse(MISSINGNO);
|
||||
imageCache.put(path, image);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,8 +1,9 @@
|
||||
package de.siphalor.was.content.product;
|
||||
|
||||
import de.siphalor.was.content.lang.I18n;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.util.ResourceBundle;
|
||||
|
||||
public interface Product {
|
||||
@NotNull
|
||||
String getPropertySpecifier();
|
||||
@@ -14,15 +15,20 @@ public interface Product {
|
||||
@NotNull
|
||||
ProductType<?> getType();
|
||||
|
||||
public boolean equals(Product product);
|
||||
|
||||
@NotNull
|
||||
default String getTranslationKey() {
|
||||
return "products." + getType().getId();
|
||||
}
|
||||
|
||||
default String getName(I18n i18n) {
|
||||
@NotNull
|
||||
default String getName(@NotNull ResourceBundle i18n) {
|
||||
return i18n.getString(getTranslationKey());
|
||||
}
|
||||
|
||||
default String getDescription(I18n i18n) {
|
||||
@NotNull
|
||||
default String getDescription(@NotNull ResourceBundle i18n) {
|
||||
String[] props = getType().getProperties();
|
||||
String[] values = getProperties();
|
||||
|
||||
@@ -39,4 +45,14 @@ public interface Product {
|
||||
|
||||
return res.toString();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
default String getTextureLocation() {
|
||||
return "textures/products/" + getType().getId() + "/" + getPropertySpecifier();
|
||||
}
|
||||
|
||||
@NotNull
|
||||
static String getPlaceholderTextureLocation() {
|
||||
return "textures/products/package.png";
|
||||
}
|
||||
}
|
||||
|
||||
@@ -55,6 +55,11 @@ public class DynamicProduct implements Product {
|
||||
return type;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Product product) {
|
||||
return super.equals(product);
|
||||
}
|
||||
|
||||
public void setYPredicate(@NotNull IntPredicate yPredicate) {
|
||||
this.yPredicate = yPredicate;
|
||||
}
|
||||
|
||||
@@ -21,12 +21,12 @@ public class Storage {
|
||||
return slots[x][y];
|
||||
}
|
||||
|
||||
public boolean move(int x1, int y1, int x2, int y2) {
|
||||
public int move(int x1, int y1, int x2, int y2) {
|
||||
StorageSlot slot1 = get(x1, y1);
|
||||
Product product = slot1.front();
|
||||
if (product != null) {
|
||||
return get(x2, y2).add(product);
|
||||
}
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,16 +29,15 @@ public class StorageSlot {
|
||||
return null;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public Product pop() {
|
||||
public int pop() {
|
||||
for (int i = products.length - 1; i >= 0; i--) {
|
||||
Product product = products[i];
|
||||
if (product != null) {
|
||||
products[i] = null;
|
||||
return product;
|
||||
return i;
|
||||
}
|
||||
}
|
||||
return null;
|
||||
return -1;
|
||||
}
|
||||
|
||||
public boolean fits(@NotNull Product product) {
|
||||
@@ -51,7 +50,7 @@ public class StorageSlot {
|
||||
return product.getDepth() <= depth - blocked;
|
||||
}
|
||||
|
||||
public boolean add(@NotNull Product product) {
|
||||
public int add(@NotNull Product product) {
|
||||
int blocked = 0;
|
||||
int i;
|
||||
for (i = 0; i < products.length; i++) {
|
||||
@@ -61,13 +60,13 @@ public class StorageSlot {
|
||||
}
|
||||
blocked += p.getDepth();
|
||||
if (blocked >= depth) {
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
if (i < products.length && product.getDepth() <= depth - blocked) {
|
||||
products[i] = product;
|
||||
return true;
|
||||
return i;
|
||||
}
|
||||
return false;
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
package de.siphalor.was.util;
|
||||
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.BufferedInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
|
||||
/**
|
||||
* <b>Taken from here: https://stackoverflow.com/questions/924990/how-to-cache-inputstream-for-multiple-use#1303314</b>
|
||||
*/
|
||||
public class PersistentInputStream extends BufferedInputStream {
|
||||
public PersistentInputStream(@NotNull InputStream in) {
|
||||
super(in);
|
||||
super.mark(Integer.MAX_VALUE);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void close() throws IOException {
|
||||
super.reset();
|
||||
}
|
||||
|
||||
public void realClose() throws IOException {
|
||||
super.close();
|
||||
}
|
||||
}
|
||||
@@ -1,17 +1,27 @@
|
||||
package de.siphalor.was.visual;
|
||||
|
||||
import de.siphalor.was.WhatAStorage;
|
||||
import de.siphalor.was.assets.AssetsManager;
|
||||
import de.siphalor.was.content.product.Product;
|
||||
import de.siphalor.was.content.quest.Quest;
|
||||
import de.siphalor.was.game.Balance;
|
||||
import de.siphalor.was.visual.canvas.layout.FixedAspectLayout;
|
||||
import de.siphalor.was.visual.canvas.layout.FulfillingLayout;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
import java.awt.*;
|
||||
import java.awt.event.*;
|
||||
import java.awt.image.BufferStrategy;
|
||||
import java.io.IOException;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
public class CanvasVisual implements Visual {
|
||||
@NotNull
|
||||
public static final Image MISSINGNO = getImage("textures/missingno.png");
|
||||
private static final double ASPECT_RATIO = 16.0 / 9.0;
|
||||
private static final Map<String, Image> imageCache = new HashMap<>();
|
||||
private WhatAStorage main;
|
||||
|
||||
private final Frame frame = new Frame(WhatAStorage.TITLE);
|
||||
@@ -21,6 +31,23 @@ public class CanvasVisual implements Visual {
|
||||
|
||||
private boolean fullScreen = false;
|
||||
|
||||
@NotNull
|
||||
public static Image getImage(@NotNull String path) {
|
||||
Image image = imageCache.get(path);
|
||||
if (image == null) {
|
||||
image = AssetsManager.getStream(path).map(inputStream -> {
|
||||
try {
|
||||
return (Image) ImageIO.read(inputStream);
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
return null;
|
||||
}).orElse(MISSINGNO);
|
||||
imageCache.put(path, image);
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(WhatAStorage whatAStorage) {
|
||||
main = whatAStorage;
|
||||
@@ -138,7 +165,17 @@ public class CanvasVisual implements Visual {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuestAbandoned(int index) {
|
||||
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) {
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2,14 +2,17 @@ package de.siphalor.was.visual;
|
||||
|
||||
import de.siphalor.was.WhatAStorage;
|
||||
import de.siphalor.was.assets.AssetsManager;
|
||||
import de.siphalor.was.content.ContentManager;
|
||||
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.content.resource.Resource;
|
||||
import de.siphalor.was.game.Balance;
|
||||
import de.siphalor.was.util.Pair;
|
||||
import de.siphalor.was.util.PersistentInputStream;
|
||||
import de.siphalor.was.visual.jfx.BalanceEntry;
|
||||
import de.siphalor.was.visual.jfx.MainController;
|
||||
import de.siphalor.was.visual.jfx.QuestController;
|
||||
import de.siphalor.was.visual.jfx.StorageSlotController;
|
||||
import javafx.application.Application;
|
||||
import javafx.collections.ObservableList;
|
||||
import javafx.fxml.FXMLLoader;
|
||||
@@ -20,10 +23,14 @@ import javafx.scene.chart.XYChart;
|
||||
import javafx.scene.control.TableColumn;
|
||||
import javafx.scene.control.cell.PropertyValueFactory;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.Pane;
|
||||
import javafx.stage.Stage;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.Optional;
|
||||
|
||||
public class JFXVisual extends Application implements Visual {
|
||||
private static Stage primaryStage;
|
||||
@@ -33,6 +40,20 @@ public class JFXVisual extends Application implements Visual {
|
||||
|
||||
private static MainController controller;
|
||||
|
||||
@NotNull
|
||||
public static Image getProductImage(@NotNull Product product, @NotNull ContentManager contentManager) {
|
||||
return loadImage(product.getTextureLocation(), contentManager).orElseGet(() -> loadImage(Product.getPlaceholderTextureLocation(), contentManager).orElseThrow());
|
||||
}
|
||||
@NotNull
|
||||
public static Optional<Image> loadImage(@NotNull String location, @NotNull ContentManager contentManager) {
|
||||
Optional<Resource> optResource = contentManager.getResource(location);
|
||||
return optResource.map(resource -> {
|
||||
InputStream inputStream = resource.getInputStream();
|
||||
if (inputStream == null) return null;
|
||||
return new Image(inputStream);
|
||||
});
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setup(WhatAStorage whatAStorage) {
|
||||
}
|
||||
@@ -52,7 +73,7 @@ public class JFXVisual extends Application implements Visual {
|
||||
I18n i18n = I18n.getInstance();
|
||||
|
||||
controller.budgetLabel.setText(i18n.format("game.budget", budget));
|
||||
if (budget < 0) {
|
||||
if (budget < 0 && !controller.budgetLabel.getStyleClass().contains("red")) {
|
||||
controller.budgetLabel.getStyleClass().add("red");
|
||||
} else {
|
||||
controller.budgetLabel.getStyleClass().remove("red");
|
||||
@@ -79,7 +100,7 @@ public class JFXVisual extends Application implements Visual {
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onQuestAbandoned(int index) {
|
||||
public void onQuestRemoved(int index) {
|
||||
controller.questBox.getChildren().remove(index);
|
||||
|
||||
controller.nextQuestButton.setDisable(false);
|
||||
@@ -95,7 +116,7 @@ public class JFXVisual extends Application implements Visual {
|
||||
controller = new MainController(WhatAStorage.getInstance());
|
||||
loader.setController(controller);
|
||||
|
||||
Pane pane = loader.load(AssetsManager.getStream("jfx/main.fxml").get());
|
||||
Pane pane = loader.load(AssetsManager.getStream("jfx/test.fxml").get());
|
||||
mainScene = new Scene(pane);
|
||||
mainScene.getStylesheets().add("assets/jfx/main.css");
|
||||
|
||||
@@ -114,6 +135,8 @@ public class JFXVisual extends Application implements Visual {
|
||||
public void loadMainScene() {
|
||||
primaryStage.setScene(mainScene);
|
||||
|
||||
prepareStorageGrid();
|
||||
|
||||
AssetsManager.getStream("textures/bin_closed.png").ifPresent(inputStream -> {
|
||||
controller.trash.setImage(new Image(inputStream));
|
||||
});
|
||||
@@ -122,11 +145,11 @@ public class JFXVisual extends Application implements Visual {
|
||||
onBalanceChanged(0, Balance.Transaction.NOOP, 0, 0, 0);
|
||||
}
|
||||
|
||||
public void addQuest(Quest quest) {
|
||||
private void addQuest(Quest quest) {
|
||||
AssetsManager.getStream("jfx/quest_widget.fxml").ifPresentOrElse(is -> {
|
||||
try {
|
||||
FXMLLoader loader = new FXMLLoader();
|
||||
QuestController questController = new QuestController(WhatAStorage.getInstance());
|
||||
QuestController questController = new QuestController(quest.getType());
|
||||
loader.setController(questController);
|
||||
Parent parent = loader.load(is);
|
||||
|
||||
@@ -135,12 +158,17 @@ public class JFXVisual extends Application implements Visual {
|
||||
Product product = quest.getProduct();
|
||||
|
||||
I18n i18n = I18n.getInstance();
|
||||
|
||||
questController.title.setText(product.getName(i18n));
|
||||
|
||||
questController.description.setText(product.getDescription(i18n));
|
||||
|
||||
questController.reward.setText(i18n.format("game.quest.reward", quest.getReward()));
|
||||
|
||||
questController.image.setImage(getProductImage(product, WhatAStorage.getInstance().getContentManager()));
|
||||
|
||||
if (quest.getType() == Quest.Type.OUT) {
|
||||
parent.getStyleClass().add("quest-out");
|
||||
}
|
||||
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
@@ -148,4 +176,89 @@ public class JFXVisual extends Application implements Visual {
|
||||
System.out.println("INTERNAL ERROR: Failed to load quest widget");
|
||||
});
|
||||
}
|
||||
|
||||
private void prepareStorageGrid() {
|
||||
GridPane storageGrid = controller.storageGrid;
|
||||
storageGrid.getChildren().clear();
|
||||
|
||||
PersistentInputStream inputStream = new PersistentInputStream(AssetsManager.getStream("jfx/storage_slot.fxml").orElseThrow());
|
||||
|
||||
for (int y = 0; y < 3; y++) {
|
||||
for (int x = 0; x < 3; x++) {
|
||||
FXMLLoader loader = new FXMLLoader();
|
||||
StorageSlotController storageSlotController = new StorageSlotController(x, y);
|
||||
loader.setController(storageSlotController);
|
||||
loader.setResources(I18n.getInstance());
|
||||
|
||||
try {
|
||||
Parent parent = loader.load(inputStream);
|
||||
inputStream.reset();
|
||||
|
||||
storageGrid.add(parent, x, y);
|
||||
controller.storageSlotControllers[y][x] = storageSlotController;
|
||||
|
||||
// TODO
|
||||
//storageSlotController.slot0.setImage(loadImage("textures/products/package.png", WhatAStorage.getInstance().getContentManager()).orElseThrow());
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
try {
|
||||
inputStream.realClose();
|
||||
} catch (IOException e) {
|
||||
e.printStackTrace();
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductSet(int x, int y, int z, Product product) {
|
||||
ContentManager contentManager = WhatAStorage.getInstance().getContentManager();
|
||||
I18n i18n = I18n.getInstance();
|
||||
|
||||
StorageSlotController slot = controller.storageSlotControllers[y][x];
|
||||
switch (z) {
|
||||
default:
|
||||
case 0:
|
||||
slot.slot0.setImage(getProductImage(product, contentManager));
|
||||
slot.slot0Description.setText(product.getDescription(i18n));
|
||||
slot.slot0Title.setText(product.getName(i18n));
|
||||
break;
|
||||
case 1:
|
||||
slot.slot1.setImage(getProductImage(product, contentManager));
|
||||
slot.slot1Description.setText(product.getDescription(i18n));
|
||||
slot.slot1Title.setText(product.getName(i18n));
|
||||
break;
|
||||
case 2:
|
||||
slot.slot2.setImage(getProductImage(product, contentManager));
|
||||
slot.slot2Description.setText(product.getDescription(i18n));
|
||||
slot.slot2Title.setText(product.getName(i18n));
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onProductCleared(int x, int y, int z) {
|
||||
StorageSlotController slot = controller.storageSlotControllers[y][x];
|
||||
String empty = I18n.getInstance().getString("game.storage.empty");
|
||||
switch (z) {
|
||||
default:
|
||||
case 0:
|
||||
slot.slot0.setImage(null);
|
||||
slot.slot0Description.setText(null);
|
||||
slot.slot0Title.setText(empty);
|
||||
break;
|
||||
case 1:
|
||||
slot.slot1.setImage(null);
|
||||
slot.slot1Description.setText(null);
|
||||
slot.slot1Title.setText(empty);
|
||||
break;
|
||||
case 2:
|
||||
slot.slot2.setImage(null);
|
||||
slot.slot2Description.setText(null);
|
||||
slot.slot2Title.setText(empty);
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
package de.siphalor.was.visual;
|
||||
|
||||
import de.siphalor.was.WhatAStorage;
|
||||
import de.siphalor.was.content.product.Product;
|
||||
import de.siphalor.was.content.quest.Quest;
|
||||
import de.siphalor.was.game.Balance;
|
||||
|
||||
@@ -12,5 +13,9 @@ public interface Visual {
|
||||
void onBalanceChanged(int budget, Balance.Transaction transaction, int change, int totalIncome, int totalLoss);
|
||||
|
||||
void onQuestAdded(Quest newQuest, boolean canCreateMore);
|
||||
void onQuestAbandoned(int index);
|
||||
void onQuestRemoved(int index);
|
||||
|
||||
void onProductSet(int x, int y, int z, Product product);
|
||||
|
||||
void onProductCleared(int x, int y, int z);
|
||||
}
|
||||
|
||||
27
src/main/java/de/siphalor/was/visual/jfx/DraggedProduct.java
Normal file
27
src/main/java/de/siphalor/was/visual/jfx/DraggedProduct.java
Normal file
@@ -0,0 +1,27 @@
|
||||
package de.siphalor.was.visual.jfx;
|
||||
|
||||
import javafx.scene.input.DataFormat;
|
||||
|
||||
import java.io.Serializable;
|
||||
|
||||
interface DraggedProduct extends Serializable {
|
||||
DataFormat FORMAT = new DataFormat("application/java-was-jfx-product-move");
|
||||
|
||||
class Quest implements DraggedProduct {
|
||||
public final int index;
|
||||
|
||||
public Quest(int index) {
|
||||
this.index = index;
|
||||
}
|
||||
}
|
||||
|
||||
class Slot implements DraggedProduct {
|
||||
public final int x;
|
||||
public final int y;
|
||||
|
||||
public Slot(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
}
|
||||
}
|
||||
25
src/main/java/de/siphalor/was/visual/jfx/JFXUtil.java
Normal file
25
src/main/java/de/siphalor/was/visual/jfx/JFXUtil.java
Normal file
@@ -0,0 +1,25 @@
|
||||
package de.siphalor.was.visual.jfx;
|
||||
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.PixelReader;
|
||||
import javafx.scene.image.PixelWriter;
|
||||
import javafx.scene.image.WritableImage;
|
||||
|
||||
public class JFXUtil {
|
||||
public static Image scaleTo(Image image, int width) {
|
||||
double scale = image.getWidth() / (double) width;
|
||||
int height = (int) (image.getHeight() / scale);
|
||||
|
||||
WritableImage res = new WritableImage(width, height);
|
||||
PixelReader reader = image.getPixelReader();
|
||||
PixelWriter writer = res.getPixelWriter();
|
||||
|
||||
for (int x = 0; x < width; x++) {
|
||||
for (int y = 0; y < height; y++) {
|
||||
writer.setColor(x, y, reader.getColor((int) (x * scale), (int) (y * scale)));
|
||||
}
|
||||
}
|
||||
|
||||
return res;
|
||||
}
|
||||
}
|
||||
@@ -1,7 +1,6 @@
|
||||
package de.siphalor.was.visual.jfx;
|
||||
|
||||
import de.siphalor.was.WhatAStorage;
|
||||
import de.siphalor.was.util.Pair;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.chart.LineChart;
|
||||
import javafx.scene.chart.NumberAxis;
|
||||
@@ -10,8 +9,12 @@ import javafx.scene.control.Button;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.control.TableView;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.DragEvent;
|
||||
import javafx.scene.input.TransferMode;
|
||||
import javafx.scene.layout.GridPane;
|
||||
import javafx.scene.layout.VBox;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class MainController {
|
||||
private final WhatAStorage was;
|
||||
|
||||
@@ -27,6 +30,9 @@ public class MainController {
|
||||
public VBox questBox;
|
||||
public Button nextQuestButton;
|
||||
|
||||
public GridPane storageGrid;
|
||||
public StorageSlotController[][] storageSlotControllers = new StorageSlotController[3][3];
|
||||
|
||||
public MainController(WhatAStorage was) {
|
||||
this.was = was;
|
||||
}
|
||||
@@ -40,4 +46,36 @@ public class MainController {
|
||||
private void nextQuest() {
|
||||
was.requestQuest();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onTrashDragOver(DragEvent dragEvent) {
|
||||
if (dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) {
|
||||
dragEvent.acceptTransferModes(TransferMode.MOVE);
|
||||
}
|
||||
|
||||
dragEvent.consume();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onTrashDragDropped(DragEvent dragEvent) {
|
||||
if (dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) {
|
||||
DraggedProduct origin = (DraggedProduct) dragEvent.getDragboard().getContent(DraggedProduct.FORMAT);
|
||||
|
||||
if (origin instanceof DraggedProduct.Quest) {
|
||||
DraggedProduct.Quest questOrigin = (DraggedProduct.Quest) origin;
|
||||
was.abandonQuest(questOrigin.index);
|
||||
|
||||
dragEvent.setDropCompleted(true);
|
||||
dragEvent.consume();
|
||||
return;
|
||||
} else if (origin instanceof DraggedProduct.Slot) {
|
||||
was.destroyProduct(((DraggedProduct.Slot) origin).x, ((DraggedProduct.Slot) origin).y);
|
||||
|
||||
dragEvent.setDropCompleted(true);
|
||||
dragEvent.consume();
|
||||
return;
|
||||
}
|
||||
}
|
||||
dragEvent.setDropCompleted(false);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,13 +1,16 @@
|
||||
package de.siphalor.was.visual.jfx;
|
||||
|
||||
import de.siphalor.was.WhatAStorage;
|
||||
import de.siphalor.was.content.quest.Quest;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.*;
|
||||
import javafx.scene.layout.GridPane;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class QuestController {
|
||||
private final WhatAStorage was;
|
||||
private final Quest.Type type;
|
||||
|
||||
@FXML
|
||||
private GridPane questContainer;
|
||||
@@ -18,13 +21,62 @@ public class QuestController {
|
||||
|
||||
public ImageView image;
|
||||
|
||||
public QuestController(WhatAStorage was) {
|
||||
this.was = was;
|
||||
public QuestController(Quest.Type type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void abandon() {
|
||||
int index = questContainer.getParent().getChildrenUnmodifiable().indexOf(questContainer);
|
||||
was.abandonQuest(index);
|
||||
WhatAStorage.getInstance().abandonQuest(getIndex());
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDragDetected(MouseEvent event) {
|
||||
if (type == Quest.Type.IN) {
|
||||
Dragboard dragboard = questContainer.startDragAndDrop(TransferMode.MOVE);
|
||||
dragboard.setDragView(JFXUtil.scaleTo(image.getImage(), 100));
|
||||
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.put(DraggedProduct.FORMAT, new DraggedProduct.Quest(getIndex()));
|
||||
dragboard.setContent(content);
|
||||
}
|
||||
|
||||
event.consume();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDragOver(DragEvent dragEvent) {
|
||||
Dragboard dragboard = dragEvent.getDragboard();
|
||||
if (dragboard.hasContent(DraggedProduct.FORMAT)) {
|
||||
DraggedProduct product = (DraggedProduct) dragboard.getContent(DraggedProduct.FORMAT);
|
||||
if (product instanceof DraggedProduct.Slot) {
|
||||
DraggedProduct.Slot slot = (DraggedProduct.Slot) product;
|
||||
if (WhatAStorage.getInstance().canSellProduct(getIndex(), slot.x, slot.y)) {
|
||||
dragEvent.acceptTransferModes(TransferMode.MOVE);
|
||||
dragEvent.consume();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDragDropped(DragEvent dragEvent) {
|
||||
Dragboard dragboard = dragEvent.getDragboard();
|
||||
if (dragboard.hasContent(DraggedProduct.FORMAT)) {
|
||||
DraggedProduct product = (DraggedProduct) dragboard.getContent(DraggedProduct.FORMAT);
|
||||
if (product instanceof DraggedProduct.Slot) {
|
||||
DraggedProduct.Slot slot = (DraggedProduct.Slot) product;
|
||||
if (WhatAStorage.getInstance().sellProduct(getIndex(), slot.x, slot.y)) {
|
||||
dragEvent.setDropCompleted(true);
|
||||
dragEvent.consume();
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
dragEvent.setDropCompleted(false);
|
||||
}
|
||||
|
||||
private int getIndex() {
|
||||
return questContainer.getParent().getChildrenUnmodifiable().indexOf(questContainer);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,94 @@
|
||||
package de.siphalor.was.visual.jfx;
|
||||
|
||||
import de.siphalor.was.WhatAStorage;
|
||||
import javafx.fxml.FXML;
|
||||
import javafx.scene.Parent;
|
||||
import javafx.scene.control.Label;
|
||||
import javafx.scene.image.Image;
|
||||
import javafx.scene.image.ImageView;
|
||||
import javafx.scene.input.*;
|
||||
|
||||
@SuppressWarnings("unused")
|
||||
public class StorageSlotController {
|
||||
private final int x;
|
||||
private final int y;
|
||||
|
||||
@FXML
|
||||
private Parent slot;
|
||||
|
||||
public ImageView slot0;
|
||||
public Label slot0Title;
|
||||
public Label slot0Description;
|
||||
|
||||
public ImageView slot1;
|
||||
public Label slot1Title;
|
||||
public Label slot1Description;
|
||||
|
||||
public ImageView slot2;
|
||||
public Label slot2Title;
|
||||
public Label slot2Description;
|
||||
|
||||
public StorageSlotController(int x, int y) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDragDetected(MouseEvent event) {
|
||||
int index;
|
||||
Image image;
|
||||
if (slot2.getImage() != null) {
|
||||
image = JFXUtil.scaleTo(slot2.getImage(), 100);
|
||||
} else if (slot1.getImage() != null) {
|
||||
image = JFXUtil.scaleTo(slot1.getImage(), 100);
|
||||
} else if (slot0.getImage() != null){
|
||||
image = JFXUtil.scaleTo(slot0.getImage(), 100);
|
||||
} else {
|
||||
event.consume();
|
||||
return;
|
||||
}
|
||||
|
||||
Dragboard dragboard = slot.startDragAndDrop(TransferMode.MOVE);
|
||||
dragboard.setDragView(image);
|
||||
ClipboardContent content = new ClipboardContent();
|
||||
content.put(DraggedProduct.FORMAT, new DraggedProduct.Slot(x, y));
|
||||
dragboard.setContent(content);
|
||||
|
||||
event.consume();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDragOver(DragEvent dragEvent) {
|
||||
if (dragEvent.getGestureSource() != slot && dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) {
|
||||
DraggedProduct origin = (DraggedProduct) dragEvent.getDragboard().getContent(DraggedProduct.FORMAT);
|
||||
if (origin instanceof DraggedProduct.Quest) {
|
||||
if (WhatAStorage.getInstance().canStoreProduct(((DraggedProduct.Quest) origin).index, x, y)) {
|
||||
dragEvent.acceptTransferModes(TransferMode.MOVE);
|
||||
}
|
||||
} else if (origin instanceof DraggedProduct.Slot){
|
||||
if (WhatAStorage.getInstance().canMoveProduct(((DraggedProduct.Slot) origin).x, ((DraggedProduct.Slot) origin).y, x, y)) {
|
||||
dragEvent.acceptTransferModes(TransferMode.MOVE);
|
||||
}
|
||||
}
|
||||
}
|
||||
dragEvent.consume();
|
||||
}
|
||||
|
||||
@FXML
|
||||
private void onDragDropped(DragEvent dragEvent) {
|
||||
if (dragEvent.getGestureSource() != slot && dragEvent.getDragboard().hasContent(DraggedProduct.FORMAT)) {
|
||||
DraggedProduct origin = (DraggedProduct) dragEvent.getDragboard().getContent(DraggedProduct.FORMAT);
|
||||
if (origin instanceof DraggedProduct.Quest) {
|
||||
WhatAStorage.getInstance().storeProduct(((DraggedProduct.Quest) origin).index, x, y);
|
||||
dragEvent.setDropCompleted(true);
|
||||
return;
|
||||
} else if (origin instanceof DraggedProduct.Slot) {
|
||||
DraggedProduct.Slot slot = (DraggedProduct.Slot) origin;
|
||||
WhatAStorage.getInstance().moveProduct(slot.x, slot.y, x, y);
|
||||
dragEvent.setDropCompleted(true);
|
||||
return;
|
||||
}
|
||||
}
|
||||
dragEvent.setDropCompleted(false);
|
||||
}
|
||||
}
|
||||
168
src/main/resources/assets/jfx/game.fxml
Normal file
168
src/main/resources/assets/jfx/game.fxml
Normal file
@@ -0,0 +1,168 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.chart.LineChart?>
|
||||
<?import javafx.scene.chart.NumberAxis?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.SplitPane?>
|
||||
<?import javafx.scene.control.Tab?>
|
||||
<?import javafx.scene.control.TabPane?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.control.ToolBar?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.AnchorPane?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox maxHeight="1.7976931348623157E308" prefWidth="800.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<AnchorPane>
|
||||
<children>
|
||||
<ToolBar maxWidth="1.7976931348623157E308" prefHeight="40.0" AnchorPane.leftAnchor="0.0" AnchorPane.rightAnchor="0.0">
|
||||
<items>
|
||||
<Label fx:id="budgetLabel" text="%game.budget">
|
||||
<font>
|
||||
<Font size="19.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</items>
|
||||
</ToolBar>
|
||||
<Button alignment="CENTER" mnemonicParsing="false" onMouseClicked="#scheduleStop" styleClass="red" text="%game.quit" textFill="WHITE" AnchorPane.rightAnchor="10.0" AnchorPane.topAnchor="7.0" />
|
||||
</children>
|
||||
</AnchorPane>
|
||||
<SplitPane dividerPositions="0.3659147869674185" maxHeight="1.7976931348623157E308" VBox.vgrow="ALWAYS">
|
||||
<items>
|
||||
<GridPane minWidth="250.0" styleClass="side-pane">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints fillHeight="false" minHeight="-Infinity" vgrow="NEVER" />
|
||||
<RowConstraints fillHeight="false" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES" />
|
||||
<RowConstraints fillHeight="false" maxHeight="-Infinity" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ScrollPane id="quest-pane" fitToWidth="true" hbarPolicy="NEVER" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<content>
|
||||
<VBox fx:id="questBox" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<VBox alignment="CENTER" onDragDropped="#onTrashDragDropped" onDragOver="#onTrashDragOver" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="TOP">
|
||||
<GridPane.margin>
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
<children>
|
||||
<ImageView fx:id="trash" fitHeight="80.0" pickOnBounds="true" preserveRatio="true" />
|
||||
<Label text="%game.trash">
|
||||
<font>
|
||||
<Font name="System Bold" size="19.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets top="10.0" />
|
||||
</padding>
|
||||
</VBox>
|
||||
<Label maxWidth="1.7976931348623157E308" minWidth="450.0" styleClass="quest-bar" text="%game.quests" GridPane.hgrow="ALWAYS" GridPane.rowIndex="1">
|
||||
<font>
|
||||
<Font size="23.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="10.0" top="-1.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Button fx:id="nextQuestButton" mnemonicParsing="false" onAction="#nextQuest" styleClass="green" text="%game.quests.next" textFill="WHITE" GridPane.halignment="RIGHT" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="5.0" />
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
</children>
|
||||
</GridPane>
|
||||
<TabPane minWidth="450.0" tabClosingPolicy="UNAVAILABLE" tabMaxHeight="Infinity" tabMaxWidth="Infinity">
|
||||
<tabs>
|
||||
<Tab text="%game.storage">
|
||||
<content>
|
||||
<GridPane id="storage-grid" fx:id="storageGrid" alignment="CENTER_LEFT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" percentWidth="33.333" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<padding>
|
||||
<Insets bottom="10.0" left="10.0" right="10.0" top="10.0" />
|
||||
</padding>
|
||||
</GridPane>
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab text="%game.balance.history">
|
||||
<content>
|
||||
<TableView fx:id="balanceHistoryTable" prefHeight="200.0" prefWidth="200.0">
|
||||
<columns>
|
||||
<TableColumn prefWidth="50.666626400416135" styleClass="align-right" text="%game.balance.history.index" />
|
||||
<TableColumn maxWidth="500.0" prefWidth="100.0" styleClass="align-right" text="%game.balance.history.change" />
|
||||
<TableColumn maxWidth="1.7976931348623157E308" prefWidth="300.0" text="%game.balance.history.type" />
|
||||
</columns>
|
||||
<placeholder>
|
||||
<Label text="%game.balance.history.no-data" />
|
||||
</placeholder>
|
||||
</TableView>
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab text="%game.balance.chart">
|
||||
<content>
|
||||
<VBox>
|
||||
<children>
|
||||
<HBox fillHeight="false" maxWidth="1.7976931348623157E308" styleClass="tab-info-bar">
|
||||
<children>
|
||||
<Label fx:id="totalIncomeLabel" styleClass="green" text="Label">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets right="20.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<Label fx:id="totalLossLabel" styleClass="red" text="Label">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="20.0" right="20.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<LineChart fx:id="budgetChart" verticalGridLinesVisible="false">
|
||||
<xAxis>
|
||||
<NumberAxis minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
|
||||
</xAxis>
|
||||
<yAxis>
|
||||
<NumberAxis side="LEFT" />
|
||||
</yAxis>
|
||||
</LineChart>
|
||||
</children>
|
||||
</VBox>
|
||||
</content>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
</items>
|
||||
</SplitPane>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -27,16 +27,21 @@ Label.green {
|
||||
}
|
||||
|
||||
.side-pane {
|
||||
-fx-border-width: 0 1;
|
||||
-fx-border-color: #aaaaaa;
|
||||
-fx-background-color: linear-gradient(to bottom, #dddddd, #aaaaaa);
|
||||
}
|
||||
|
||||
.quest-bar {
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-border-color: #aaaaaa;
|
||||
}
|
||||
.quest-container {
|
||||
-fx-border-width: 1 0 0 0;
|
||||
-fx-border-width: 0 0 1 0;
|
||||
-fx-border-color: #aaaaaa;
|
||||
-fx-background-color: #eeeeee;
|
||||
}
|
||||
.quest-container.quest-out ImageView {
|
||||
-fx-blend-mode: hard-light;
|
||||
}
|
||||
.quest-reward {
|
||||
-fx-text-fill: #457229;
|
||||
}
|
||||
@@ -49,7 +54,31 @@ Label.green {
|
||||
.table-column {
|
||||
-fx-padding: 0 5;
|
||||
}
|
||||
.split-pane:horizontal > .split-pane-divider {
|
||||
-fx-padding: 0 1 0 1;
|
||||
-fx-background-color: #aaaaaa;
|
||||
}
|
||||
.tab-pane:top > .tab-header-area {
|
||||
-fx-min-height: 34;
|
||||
-fx-pref-height: 34;
|
||||
}
|
||||
.tab-pane:top > .tab-header-area > .headers-region > .tab {
|
||||
-fx-padding: 4;
|
||||
-fx-end-margin: 5;
|
||||
}
|
||||
.tab-pane:top > .tab-header-area > .headers-region > .tab .focus-indicator {
|
||||
-fx-focus-color: transparent;
|
||||
-fx-faint-focus-color: transparent;
|
||||
}
|
||||
|
||||
#main {
|
||||
-fx-background-color: #dddddd;
|
||||
}
|
||||
|
||||
#storage-grid > * {
|
||||
-fx-border-color: #dddddd;
|
||||
-fx-border-width: 1;
|
||||
}
|
||||
.storage-slot-item-title {
|
||||
-fx-end-margin: 10;
|
||||
}
|
||||
|
||||
@@ -1,163 +0,0 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.geometry.Insets?>
|
||||
<?import javafx.scene.chart.LineChart?>
|
||||
<?import javafx.scene.chart.NumberAxis?>
|
||||
<?import javafx.scene.control.Accordion?>
|
||||
<?import javafx.scene.control.Button?>
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.control.ScrollPane?>
|
||||
<?import javafx.scene.control.Tab?>
|
||||
<?import javafx.scene.control.TabPane?>
|
||||
<?import javafx.scene.control.TableColumn?>
|
||||
<?import javafx.scene.control.TableView?>
|
||||
<?import javafx.scene.control.ToolBar?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<GridPane maxHeight="-Infinity" maxWidth="-Infinity" minHeight="-Infinity" minWidth="-Infinity" prefHeight="450.0" prefWidth="850.0" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="250.0" percentWidth="30.0" prefWidth="250.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="1.7976931348623157E308" minWidth="10.0" percentWidth="70.0" prefWidth="380.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints fillHeight="false" vgrow="NEVER" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<GridPane styleClass="side-pane" GridPane.rowIndex="1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints fillHeight="false" minHeight="-Infinity" vgrow="NEVER" />
|
||||
<RowConstraints fillHeight="false" vgrow="NEVER" />
|
||||
<RowConstraints maxHeight="1.7976931348623157E308" vgrow="SOMETIMES" />
|
||||
<RowConstraints fillHeight="false" maxHeight="-Infinity" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ScrollPane id="quest-pane" fitToWidth="true" hbarPolicy="NEVER" prefHeight="200.0" prefWidth="200.0" GridPane.rowIndex="2">
|
||||
<content>
|
||||
<VBox fx:id="questBox" />
|
||||
</content>
|
||||
</ScrollPane>
|
||||
<Label text="%game.trash" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="BOTTOM">
|
||||
<font>
|
||||
<Font name="System Bold" size="19.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<ImageView fx:id="trash" fitHeight="80.0" pickOnBounds="true" preserveRatio="true" GridPane.halignment="CENTER" GridPane.rowIndex="3" GridPane.valignment="TOP">
|
||||
<GridPane.margin>
|
||||
<Insets bottom="35.0" top="10.0" />
|
||||
</GridPane.margin>
|
||||
</ImageView>
|
||||
<Label text="%game.quests" GridPane.rowIndex="1">
|
||||
<font>
|
||||
<Font size="23.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="10.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
<Button fx:id="nextQuestButton" mnemonicParsing="false" onAction="#nextQuest" styleClass="green" text="%game.quests.next" textFill="WHITE" GridPane.halignment="RIGHT" GridPane.rowIndex="1" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="5.0" />
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
<Accordion GridPane.rowIndex="1" />
|
||||
</children>
|
||||
</GridPane>
|
||||
<TabPane tabClosingPolicy="UNAVAILABLE" GridPane.columnIndex="1" GridPane.rowIndex="1">
|
||||
<GridPane.margin>
|
||||
<Insets />
|
||||
</GridPane.margin>
|
||||
<tabs>
|
||||
<Tab text="%game.storage">
|
||||
<content>
|
||||
<GridPane>
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" minWidth="10.0" prefWidth="100.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
</GridPane>
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab text="%game.balance.history">
|
||||
<content>
|
||||
<TableView fx:id="balanceHistoryTable" prefHeight="200.0" prefWidth="200.0">
|
||||
<columns>
|
||||
<TableColumn prefWidth="50.666626400416135" styleClass="align-right" text="%game.balance.history.index" />
|
||||
<TableColumn maxWidth="500.0" prefWidth="149.77776718139648" styleClass="align-right" text="%game.balance.history.change" />
|
||||
<TableColumn maxWidth="1.7976931348623157E308" prefWidth="400.0" text="%game.balance.history.type" />
|
||||
</columns>
|
||||
</TableView>
|
||||
</content>
|
||||
</Tab>
|
||||
<Tab text="%game.balance.chart">
|
||||
<content>
|
||||
<VBox>
|
||||
<children>
|
||||
<HBox fillHeight="false" maxWidth="1.7976931348623157E308" styleClass="tab-info-bar">
|
||||
<children>
|
||||
<Label fx:id="totalIncomeLabel" styleClass="green" text="Label">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
<HBox.margin>
|
||||
<Insets right="20.0" />
|
||||
</HBox.margin>
|
||||
</Label>
|
||||
<Label fx:id="totalLossLabel" styleClass="red" text="Label">
|
||||
<font>
|
||||
<Font size="14.0" />
|
||||
</font>
|
||||
</Label>
|
||||
</children>
|
||||
<padding>
|
||||
<Insets bottom="5.0" left="20.0" right="20.0" top="5.0" />
|
||||
</padding>
|
||||
</HBox>
|
||||
<LineChart fx:id="budgetChart" verticalGridLinesVisible="false">
|
||||
<xAxis>
|
||||
<NumberAxis minorTickVisible="false" side="BOTTOM" tickLabelsVisible="false" tickMarkVisible="false" />
|
||||
</xAxis>
|
||||
<yAxis>
|
||||
<NumberAxis side="LEFT" />
|
||||
</yAxis>
|
||||
</LineChart>
|
||||
</children>
|
||||
</VBox>
|
||||
</content>
|
||||
</Tab>
|
||||
</tabs>
|
||||
</TabPane>
|
||||
<ToolBar prefHeight="40.0" prefWidth="200.0" GridPane.columnSpan="2147483647">
|
||||
<items>
|
||||
<Label fx:id="budgetLabel" text="%game.budget">
|
||||
<font>
|
||||
<Font size="19.0" />
|
||||
</font>
|
||||
<padding>
|
||||
<Insets left="5.0" />
|
||||
</padding>
|
||||
</Label>
|
||||
</items>
|
||||
</ToolBar>
|
||||
<Button mnemonicParsing="false" onMouseClicked="#scheduleStop" styleClass="red" text="%game.quit" textFill="WHITE" GridPane.columnSpan="2147483647" GridPane.halignment="RIGHT" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets right="10.0" />
|
||||
</GridPane.margin>
|
||||
</Button>
|
||||
</children>
|
||||
</GridPane>
|
||||
@@ -10,7 +10,7 @@
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<GridPane fx:id="questContainer" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="250.0" prefHeight="80.0" styleClass="quest-container" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<GridPane fx:id="questContainer" maxHeight="-Infinity" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="250.0" onDragDetected="#onDragDetected" onDragDropped="#onDragDropped" onDragOver="#onDragOver" prefHeight="80.0" styleClass="quest-container" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="80.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" />
|
||||
@@ -20,9 +20,9 @@
|
||||
<RowConstraints minHeight="10.0" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="image" fitHeight="80.0" fitWidth="100.0" pickOnBounds="true" preserveRatio="true" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<ImageView fx:id="image" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
<GridPane.margin>
|
||||
<Insets />
|
||||
<Insets bottom="5.0" left="5.0" right="5.0" top="5.0" />
|
||||
</GridPane.margin>
|
||||
</ImageView>
|
||||
<Button maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" minHeight="-Infinity" minWidth="-Infinity" mnemonicParsing="false" onAction="#abandon" prefHeight="0.0" prefWidth="0.0" styleClass="red" text="X" textFill="WHITE" GridPane.columnIndex="2" GridPane.halignment="CENTER" GridPane.valignment="CENTER">
|
||||
|
||||
65
src/main/resources/assets/jfx/storage_slot.fxml
Normal file
65
src/main/resources/assets/jfx/storage_slot.fxml
Normal file
@@ -0,0 +1,65 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
|
||||
<?import javafx.scene.control.Label?>
|
||||
<?import javafx.scene.image.ImageView?>
|
||||
<?import javafx.scene.layout.ColumnConstraints?>
|
||||
<?import javafx.scene.layout.GridPane?>
|
||||
<?import javafx.scene.layout.HBox?>
|
||||
<?import javafx.scene.layout.RowConstraints?>
|
||||
<?import javafx.scene.layout.VBox?>
|
||||
<?import javafx.scene.text.Font?>
|
||||
|
||||
<VBox fx:id="slot" fillWidth="false" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308" onDragDetected="#onDragDetected" onDragDropped="#onDragDropped" onDragOver="#onDragOver" GridPane.valignment="CENTER" xmlns="http://javafx.com/javafx/9.0.1" xmlns:fx="http://javafx.com/fxml/1">
|
||||
<children>
|
||||
<GridPane alignment="CENTER_LEFT" maxHeight="1.7976931348623157E308" maxWidth="1.7976931348623157E308">
|
||||
<columnConstraints>
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="30.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="30.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="30.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="-Infinity" prefWidth="30.0" />
|
||||
<ColumnConstraints hgrow="SOMETIMES" maxWidth="-Infinity" minWidth="0.0" />
|
||||
</columnConstraints>
|
||||
<rowConstraints>
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
<RowConstraints maxHeight="-Infinity" minHeight="-Infinity" prefHeight="30.0" vgrow="SOMETIMES" />
|
||||
</rowConstraints>
|
||||
<children>
|
||||
<ImageView fx:id="slot0" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="2" GridPane.columnSpan="2" GridPane.rowSpan="2" />
|
||||
<ImageView fx:id="slot1" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnIndex="1" GridPane.columnSpan="2" GridPane.rowIndex="1" GridPane.rowSpan="2" />
|
||||
<ImageView fx:id="slot2" fitHeight="60.0" fitWidth="60.0" pickOnBounds="true" preserveRatio="true" GridPane.columnSpan="2" GridPane.rowIndex="2" GridPane.rowSpan="2" />
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="100.0" GridPane.columnIndex="4" GridPane.rowIndex="1">
|
||||
<children>
|
||||
<Label fx:id="slot0Title" styleClass="storage-slot-item-title" text="%game.storage.empty">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label fx:id="slot0Description" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="100.0" GridPane.columnIndex="3" GridPane.columnSpan="2147483647" GridPane.rowIndex="2">
|
||||
<children>
|
||||
<Label fx:id="slot1Title" styleClass="storage-slot-item-title" text="%game.storage.empty">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label fx:id="slot1Description" />
|
||||
</children>
|
||||
</HBox>
|
||||
<HBox alignment="CENTER_LEFT" prefHeight="100.0" GridPane.columnIndex="2" GridPane.columnSpan="2147483647" GridPane.rowIndex="3">
|
||||
<children>
|
||||
<Label fx:id="slot2Title" styleClass="storage-slot-item-title" text="%game.storage.empty">
|
||||
<font>
|
||||
<Font name="System Bold" size="12.0" />
|
||||
</font>
|
||||
</Label>
|
||||
<Label fx:id="slot2Description" />
|
||||
</children>
|
||||
</HBox>
|
||||
</children>
|
||||
</GridPane>
|
||||
</children>
|
||||
</VBox>
|
||||
@@ -8,7 +8,9 @@ game.quest.reward = %d$
|
||||
game.trash = Recycle Bin
|
||||
game.trash.hover = Destroy\n%d$
|
||||
game.storage = Storage
|
||||
game.storage.empty = Empty
|
||||
game.balance.history = Transactions
|
||||
game.balance.history.no-data = No transactions yet
|
||||
game.balance.history.index =
|
||||
game.balance.history.change = Change in $
|
||||
game.balance.history.type = Description
|
||||
|
||||
BIN
src/main/resources/content/textures/products/package.png
Normal file
BIN
src/main/resources/content/textures/products/package.png
Normal file
Binary file not shown.
|
After Width: | Height: | Size: 3.4 KiB |
120
src/main/resources/content/textures/products/package.svg
Normal file
120
src/main/resources/content/textures/products/package.svg
Normal file
@@ -0,0 +1,120 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<svg
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
inkscape:version="1.0 (4035a4fb49, 2020-05-01)"
|
||||
sodipodi:docname="package.svg"
|
||||
id="svg8"
|
||||
version="1.1"
|
||||
viewBox="0 0 132.29166 132.29167"
|
||||
height="500"
|
||||
width="500">
|
||||
<defs
|
||||
id="defs2" />
|
||||
<sodipodi:namedview
|
||||
inkscape:guide-bbox="true"
|
||||
inkscape:lockguides="false"
|
||||
showguides="true"
|
||||
inkscape:window-maximized="1"
|
||||
inkscape:window-y="-7"
|
||||
inkscape:window-x="-7"
|
||||
inkscape:window-height="1010"
|
||||
inkscape:window-width="1920"
|
||||
units="px"
|
||||
showgrid="false"
|
||||
inkscape:document-rotation="0"
|
||||
inkscape:current-layer="layer1"
|
||||
inkscape:document-units="mm"
|
||||
inkscape:cy="217.09446"
|
||||
inkscape:cx="307.26355"
|
||||
inkscape:zoom="0.7"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base">
|
||||
<sodipodi:guide
|
||||
inkscape:color="rgb(0,0,255)"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
id="guide1410"
|
||||
orientation="0,1"
|
||||
position="105.83333,105.83333" />
|
||||
<sodipodi:guide
|
||||
inkscape:color="rgb(0,0,255)"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
id="guide1412"
|
||||
orientation="-1,0"
|
||||
position="105.83333,105.83333" />
|
||||
<sodipodi:guide
|
||||
inkscape:color="rgb(0,0,255)"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
id="guide1414"
|
||||
orientation="-1,0"
|
||||
position="26.458333,105.83333" />
|
||||
<sodipodi:guide
|
||||
inkscape:color="rgb(0,0,255)"
|
||||
inkscape:locked="false"
|
||||
inkscape:label=""
|
||||
id="guide1416"
|
||||
orientation="0,1"
|
||||
position="105.83333,26.458333" />
|
||||
<sodipodi:guide
|
||||
id="guide1418"
|
||||
orientation="0,500"
|
||||
position="0,132.29166" />
|
||||
<sodipodi:guide
|
||||
id="guide1420"
|
||||
orientation="500,0"
|
||||
position="132.29166,132.29166" />
|
||||
<sodipodi:guide
|
||||
id="guide1422"
|
||||
orientation="0,-500"
|
||||
position="132.29166,0" />
|
||||
<sodipodi:guide
|
||||
id="guide1424"
|
||||
orientation="-500,0"
|
||||
position="0,0" />
|
||||
</sodipodi:namedview>
|
||||
<metadata
|
||||
id="metadata5">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
<dc:title></dc:title>
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<g
|
||||
id="layer1"
|
||||
inkscape:groupmode="layer"
|
||||
inkscape:label="Layer 1">
|
||||
<rect
|
||||
ry="1.9382317e-06"
|
||||
y="26.458336"
|
||||
x="0"
|
||||
height="105.83333"
|
||||
width="105.83333"
|
||||
id="rect1426"
|
||||
style="fill:#d6b285;stroke-width:0.264583;fill-opacity:1;stroke:#000000;stroke-opacity:1" />
|
||||
<path
|
||||
id="path1428"
|
||||
d="M 0,26.458336 26.458333,4.9999997e-6 H 132.29166 L 105.83333,26.458336 H 0"
|
||||
style="fill:#e4ccaf;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
|
||||
<path
|
||||
id="path1430"
|
||||
d="m 105.83333,132.29166 26.45833,-26.45833 V 4.9999997e-6 L 105.83333,26.458336 Z"
|
||||
style="fill:#ba915e;stroke:#000000;stroke-width:0.264583px;stroke-linecap:butt;stroke-linejoin:miter;stroke-opacity:1;fill-opacity:1" />
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 3.6 KiB |
Reference in New Issue
Block a user