diff --git a/build.gradle.kts b/build.gradle.kts index 9496356..fa6628e 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -13,8 +13,23 @@ dependencies { testImplementation(platform("org.junit:junit-bom:5.10.0")) testImplementation("org.junit.jupiter:junit-jupiter") testRuntimeOnly("org.junit.platform:junit-platform-launcher") + + implementation("com.fasterxml.jackson.core:jackson-databind:2.20.0") + implementation("org.apache.commons:commons-lang3:3.19.0") } tasks.test { useJUnitPlatform() +} + +tasks.withType { + manifest { + attributes["Main-Class"] = "de.umarumg.Main" + } + + duplicatesStrategy = DuplicatesStrategy.EXCLUDE + + from({ + configurations.runtimeClasspath.get().filter { it.name.endsWith("jar") }.map { zipTree(it) } + }) } \ No newline at end of file diff --git a/src/main/java/de/umarumg/Decision.java b/src/main/java/de/umarumg/Decision.java new file mode 100644 index 0000000..935a6fd --- /dev/null +++ b/src/main/java/de/umarumg/Decision.java @@ -0,0 +1,14 @@ +package de.umarumg; + +public class Decision { + private String text; + private String scene; + + public String getText() { + return text; + } + + public String getScene() { + return scene; + } +} diff --git a/src/main/java/de/umarumg/Main.java b/src/main/java/de/umarumg/Main.java index 065f5d6..899b2eb 100644 --- a/src/main/java/de/umarumg/Main.java +++ b/src/main/java/de/umarumg/Main.java @@ -1,7 +1,126 @@ package de.umarumg; +import com.fasterxml.jackson.core.type.TypeReference; +import com.fasterxml.jackson.databind.ObjectMapper; +import org.apache.commons.lang3.StringUtils; + +import java.io.File; +import java.io.FileInputStream; +import java.io.InputStream; +import java.util.Arrays; +import java.util.LinkedList; +import java.util.Map; +import java.util.Scanner; +import java.util.concurrent.TimeUnit; +import java.util.logging.Logger; +import java.util.stream.Collectors; + public class Main { + + public static Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME); + public static Scanner scanner = new Scanner(System.in); + + private static Map story; + private static TextSpeed textSpeed = TextSpeed.NORMAL; + private static final String finalSpeeds = Arrays.stream(TextSpeed.values()) + .map(speed -> StringUtils.capitalize(speed.name().toLowerCase())) + .collect(Collectors.joining(", ")); + + private static String currentScene = "start"; + public static void main(String[] args) { - System.out.println("Hello World!"); + if (args.length > 0) { + loadDialog(args[0]); + } else { + loadDialogFromResources("dialog.json"); + } + + System.out.println("How fast should the text scroll?: " + finalSpeeds); + System.out.print("> "); + String data = scanner.nextLine().toLowerCase(); + + if (data.startsWith("s")) { + textSpeed = TextSpeed.SLOW; + } else if (data.startsWith("n")) { + textSpeed = TextSpeed.NORMAL; + } else if (data.startsWith("f")) { + textSpeed = TextSpeed.FAST; + } + + run(currentScene); + } + + public static void loadDialogFromResources(String fileName) { + try { + InputStream dialogJson = Thread.currentThread().getContextClassLoader().getResourceAsStream(fileName); + ObjectMapper mapper = new ObjectMapper(); + story = mapper.readValue(dialogJson, new TypeReference<>() { + }); + } catch (Exception ex) { + logger.severe("Error reading the internal dialog File. Exiting now!"); + System.exit(1); + } + } + + public static void loadDialog(String fileName) { + try { + InputStream dialogJson = new FileInputStream(fileName); + ObjectMapper mapper = new ObjectMapper(); + story = mapper.readValue(dialogJson, new TypeReference<>() { + }); + } catch (Exception ex) { + logger.severe("Error reading the internal dialog File. Exiting now!"); + System.exit(1); + } + } + + public static void writeText(String text) { + try { + for (char c : text.toCharArray()) { + System.out.print(c); + TimeUnit.MILLISECONDS.sleep(textSpeed.getSpeed()); + } + } catch (Exception ex) { + logger.severe("Error while writing text to screen. Exiting now!"); + System.exit(1); + } + } + + public static void run(String key) { + if (story != null) { + Scene scene = story.get(key); + for (int i = 0; i < scene.getText().size(); i++) { + writeText(scene.getText().get(i)); + if (i == scene.getText().size() - 1) { + System.out.print("\n"); + break; + } + scanner.nextLine(); + } + + LinkedList decisions = scene.getDecisions(); + + if (!decisions.isEmpty()) { + int choice = 0; + for (int i = 0; i < decisions.size(); i++) { + writeText(i+1 + ": " + decisions.get(i).getText() + "\n"); + } + + while (choice == 0) { + System.out.print("> "); + if (scanner.hasNextInt()) { + choice = scanner.nextInt(); + if (choice < 0 || choice > decisions.size()) { + choice = 0; + } + } + } + + currentScene = decisions.get(choice-1).getScene(); + run(currentScene); + } else { + System.out.println("End of Story!"); + } + } } } \ No newline at end of file diff --git a/src/main/java/de/umarumg/Scene.java b/src/main/java/de/umarumg/Scene.java new file mode 100644 index 0000000..86a85d5 --- /dev/null +++ b/src/main/java/de/umarumg/Scene.java @@ -0,0 +1,16 @@ +package de.umarumg; + +import java.util.LinkedList; + +public class Scene { + private LinkedList text; + private LinkedList decisions; + + public LinkedList getText() { + return text; + } + + public LinkedList getDecisions() { + return decisions; + } +} diff --git a/src/main/java/de/umarumg/TextSpeed.java b/src/main/java/de/umarumg/TextSpeed.java new file mode 100644 index 0000000..09d4029 --- /dev/null +++ b/src/main/java/de/umarumg/TextSpeed.java @@ -0,0 +1,17 @@ +package de.umarumg; + +public enum TextSpeed { + SLOW(100L), + NORMAL(25L), + FAST(10L); + + private final Long speed; + + TextSpeed(Long speed) { + this.speed = speed; + } + + public Long getSpeed() { + return speed; + } +} diff --git a/src/main/resources/dialog.json b/src/main/resources/dialog.json new file mode 100644 index 0000000..7dd9b10 --- /dev/null +++ b/src/main/resources/dialog.json @@ -0,0 +1,31 @@ +{ + "start": { + "text": [ + "Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet. Lorem ipsum dolor sit amet, consetetur sadipscing elitr, sed diam nonumy eirmod tempor invidunt ut labore et dolore magna aliquyam erat, sed diam voluptua. At vero eos et accusam et justo duo dolores et ea rebum. Stet clita kasd gubergren, no sea takimata sanctus est Lorem ipsum dolor sit amet.", + "That is wierd", + "What will you choose?" + ], + "decisions": [ + { + "text": "Hello World 1", + "scene": "helloworld1" + }, + { + "text": "Hello World 2", + "scene": "helloworld2" + } + ] + }, + "helloworld1": { + "text": [ + "This is Hello World 1" + ], + "decisions": [] + }, + "helloworld2": { + "text": [ + "This is Hello World 2" + ], + "decisions": [] + } +} \ No newline at end of file