diff --git a/pom.xml b/pom.xml
index a815d6b..9e81c13 100644
--- a/pom.xml
+++ b/pom.xml
@@ -23,6 +23,8 @@
1.18.38
+ 25
+ 25
@@ -152,4 +154,4 @@
6.1.1-1.5.10
-
\ No newline at end of file
+
diff --git a/src/main/java/cz/jzitnik/events/PlayVideo.java b/src/main/java/cz/jzitnik/events/PlayVideo.java
deleted file mode 100644
index dc2f5c1..0000000
--- a/src/main/java/cz/jzitnik/events/PlayVideo.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package cz.jzitnik.events;
-
-import cz.jzitnik.utils.events.Event;
-import lombok.AllArgsConstructor;
-import lombok.Getter;
-
-@Getter
-@AllArgsConstructor
-public class PlayVideo implements Event {
- private String fileName;
-}
diff --git a/src/main/java/cz/jzitnik/events/handlers/PlayVideoHandler.java b/src/main/java/cz/jzitnik/events/handlers/PlayVideoHandler.java
deleted file mode 100644
index da2c168..0000000
--- a/src/main/java/cz/jzitnik/events/handlers/PlayVideoHandler.java
+++ /dev/null
@@ -1,48 +0,0 @@
-package cz.jzitnik.events.handlers;
-
-import com.googlecode.lanterna.TextColor;
-import com.googlecode.lanterna.screen.Screen;
-import com.googlecode.lanterna.screen.TerminalScreen;
-import cz.jzitnik.annotations.EventHandler;
-import cz.jzitnik.annotations.injectors.InjectDependency;
-import cz.jzitnik.annotations.injectors.InjectState;
-import cz.jzitnik.events.PlayVideo;
-import cz.jzitnik.game.ResourceManager;
-import cz.jzitnik.states.TerminalState;
-import cz.jzitnik.utils.DependencyManager;
-import cz.jzitnik.utils.events.AbstractEventHandler;
-import org.bytedeco.javacv.FFmpegFrameGrabber;
-import org.bytedeco.javacv.Frame;
-import org.bytedeco.javacv.Java2DFrameConverter;
-
-import java.awt.*;
-import java.awt.image.BufferedImage;
-import java.io.File;
-import java.io.InputStream;
-import java.nio.file.Files;
-import java.nio.file.StandardCopyOption;
-
-@EventHandler(PlayVideo.class)
-public class PlayVideoHandler extends AbstractEventHandler {
- public PlayVideoHandler(DependencyManager dm) {
- super(dm);
- }
-
- @InjectDependency
- private ResourceManager resourceManager;
-
- @InjectState
- private TerminalState terminalState;
-
- @Override
- public void handle(PlayVideo event) {
- }
-
-
- private static TextColor.RGB toColor(int rgb) {
- int r = (rgb >> 16) & 0xFF;
- int g = (rgb >> 8) & 0xFF;
- int b = rgb & 0xFF;
- return new TextColor.RGB(r, g, b);
- }
-}
diff --git a/src/main/java/cz/jzitnik/events/handlers/TerminalResizeEventHandler.java b/src/main/java/cz/jzitnik/events/handlers/TerminalResizeEventHandler.java
index c876b3f..2f3e971 100644
--- a/src/main/java/cz/jzitnik/events/handlers/TerminalResizeEventHandler.java
+++ b/src/main/java/cz/jzitnik/events/handlers/TerminalResizeEventHandler.java
@@ -5,7 +5,6 @@ import cz.jzitnik.annotations.EventHandler;
import cz.jzitnik.annotations.injectors.InjectDependency;
import cz.jzitnik.annotations.injectors.InjectState;
import cz.jzitnik.events.FullRoomDraw;
-import cz.jzitnik.events.PlayVideo;
import cz.jzitnik.events.TerminalResizeEvent;
import cz.jzitnik.game.GameState;
import cz.jzitnik.states.ScreenBuffer;
@@ -32,6 +31,8 @@ public class TerminalResizeEventHandler extends AbstractEventHandler {
+ while (play) {
+ soundPlayer.playSound("audio/menu.ogg", 30, 100);
+ }
+ }).start();
+ }
+
+ @Override
+ public void handleMouseAction(MouseAction event) {
+
+ }
+
+ @Override
+ public void handleKeyboardAction(KeyboardPressEvent event) {
+
+ }
+ }
+
+ private static final class ImageScene extends BasicImageScene {
+ @InjectState
+ private GameState gameState;
+
+ @InjectDependency
+ private EventManager eventManager;
+
+ private final GameMenuScreen gameMenuScreen;
+
+ public ImageScene(String filePath, GameMenuScreen gameMenuScreen) {
+ super(filePath);
+ this.gameMenuScreen = gameMenuScreen;
+ }
+
+ @Override
+ public void handleKeyboardAction(KeyboardPressEvent event) {
+ if (event.getKeyStroke().getKeyType() == KeyType.Enter) {
+ gameMenuScreen.play = false;
+ gameMenuScreen.soundPlayer.stopCurrentSound();
+ gameState.setScreen(null);
+ eventManager.emitEvent(new FullRoomDraw(true));
+ }
+ }
+ }
+
+ public GameMenuScene(DependencyManager dependencyManager) {
+ GameMenuScreen gameMenuScreen = new GameMenuScreen();
+ ImageScene basicImageScene = new ImageScene("menu.png", gameMenuScreen);
+
+ super(new Screen[]{gameMenuScreen, basicImageScene}, new OnEndAction.Repeat());
+
+ dependencyManager.inject(this);
+ dependencyManager.inject(basicImageScene);
+ }
+}
diff --git a/src/main/java/cz/jzitnik/game/setup/GameSetup.java b/src/main/java/cz/jzitnik/game/setup/GameSetup.java
index 9c75690..0b07fa7 100644
--- a/src/main/java/cz/jzitnik/game/setup/GameSetup.java
+++ b/src/main/java/cz/jzitnik/game/setup/GameSetup.java
@@ -11,7 +11,6 @@ import cz.jzitnik.game.items.GameItem;
import cz.jzitnik.game.items.WoodenSword;
import cz.jzitnik.game.objects.Chest;
import cz.jzitnik.game.utils.RoomCords;
-import cz.jzitnik.screens.scenes.IntroScene;
import cz.jzitnik.utils.DependencyManager;
@Dependency
@@ -31,9 +30,13 @@ public class GameSetup {
GameRoom mainRoom = new GameRoom(ResourceManager.Resource.ROOM1);
GameRoom rightRoom = new GameRoom(ResourceManager.Resource.ROOM2);
GameRoom topRightRoom = new GameRoom(ResourceManager.Resource.ROOM3);
+ GameRoom topRightTop = new GameRoom(ResourceManager.Resource.ROOM4);
+ GameRoom topRightTopLeft = new GameRoom(ResourceManager.Resource.ROOM_FROZEN);
mainRoom.setRight(rightRoom);
rightRoom.setUp(topRightRoom);
+ topRightRoom.setUp(topRightTop);
+ topRightTop.setLeft(topRightTopLeft);
Chest chest = new Chest(dependencyManager, resourceManager, new RoomCords(100, 45), new GameItem[]{
new WoodenSword(resourceManager),
diff --git a/src/main/java/cz/jzitnik/screens/scenes/IntroScene.java b/src/main/java/cz/jzitnik/game/setup/IntroScene.java
similarity index 64%
rename from src/main/java/cz/jzitnik/screens/scenes/IntroScene.java
rename to src/main/java/cz/jzitnik/game/setup/IntroScene.java
index ee1c3be..9cb07a7 100644
--- a/src/main/java/cz/jzitnik/screens/scenes/IntroScene.java
+++ b/src/main/java/cz/jzitnik/game/setup/IntroScene.java
@@ -1,6 +1,8 @@
-package cz.jzitnik.screens.scenes;
+package cz.jzitnik.game.setup;
import cz.jzitnik.screens.Screen;
+import cz.jzitnik.screens.scenes.Scene;
+import cz.jzitnik.screens.scenes.VideoSceneWithAudio;
import cz.jzitnik.utils.DependencyManager;
public class IntroScene extends Scene {
@@ -9,7 +11,7 @@ public class IntroScene extends Scene {
new Screen[]{
new VideoSceneWithAudio("video.mp4", "audio.ogg")
},
- OnEndAction.SWITCH_TO_GAME
+ new OnEndAction.SwitchToScreen(new GameMenuScene(dependencyManager))
);
dependencyManager.inject(this);
}
diff --git a/src/main/java/cz/jzitnik/screens/scenes/BasicImageScene.java b/src/main/java/cz/jzitnik/screens/scenes/BasicImageScene.java
new file mode 100644
index 0000000..d8a5c0c
--- /dev/null
+++ b/src/main/java/cz/jzitnik/screens/scenes/BasicImageScene.java
@@ -0,0 +1,105 @@
+package cz.jzitnik.screens.scenes;
+
+import com.googlecode.lanterna.TextColor;
+import com.googlecode.lanterna.screen.TerminalScreen;
+import cz.jzitnik.annotations.injectors.InjectDependency;
+import cz.jzitnik.annotations.injectors.InjectState;
+import cz.jzitnik.events.KeyboardPressEvent;
+import cz.jzitnik.events.MouseAction;
+import cz.jzitnik.game.ResourceManager;
+import cz.jzitnik.screens.Screen;
+import cz.jzitnik.states.TerminalState;
+
+import java.awt.image.BufferedImage;
+import java.io.IOException;
+
+public class BasicImageScene extends Screen {
+ @InjectDependency
+ private ResourceManager resourceManager;
+
+ @InjectState
+ private TerminalState terminalState;
+
+ private final String imagePath;
+
+ public BasicImageScene(String filePath) {
+ imagePath = filePath;
+ }
+
+ @Override
+ public void fullRender() {
+ BufferedImage image = resourceManager.getResource(imagePath);
+ TerminalScreen screen = terminalState.getTerminalScreen();
+ screen.clear();
+ var tg = terminalState.getTextGraphics();
+
+ int termWidth = screen.getTerminalSize().getColumns();
+ int termHeight = screen.getTerminalSize().getRows();
+
+ int imgWidth = image.getWidth();
+ int imgHeight = image.getHeight();
+
+ // Terminal pixel space (because 1 cell = 2 vertical pixels)
+ int termPixelWidth = termWidth;
+ int termPixelHeight = termHeight * 2;
+
+ // Scale while preserving aspect ratio
+ double scale = Math.min(
+ (double) termPixelWidth / imgWidth,
+ (double) termPixelHeight / imgHeight
+ );
+
+ int scaledWidth = (int) (imgWidth * scale);
+ int scaledHeight = (int) (imgHeight * scale);
+
+ // Centering offsets (in pixel space)
+ int xOffset = (termPixelWidth - scaledWidth) / 2;
+ int yOffset = (termPixelHeight - scaledHeight) / 2;
+
+ for (int y = 0; y < scaledHeight / 2; y++) {
+ int imgYTop = (int) ((y * 2) / scale);
+ int imgYBottom = (int) ((y * 2 + 1) / scale);
+
+ int termY = y + (yOffset / 2);
+ if (termY < 0 || termY >= termHeight) continue;
+
+ for (int x = 0; x < scaledWidth; x++) {
+ int termX = x + xOffset;
+ if (termX < 0 || termX >= termWidth) continue;
+
+ int imgX = (int) (x / scale);
+
+ int topPixel = image.getRGB(imgX, imgYTop);
+ int bottomPixel = image.getRGB(imgX, imgYBottom);
+
+ tg.setBackgroundColor(toColor(topPixel));
+ tg.setForegroundColor(toColor(bottomPixel));
+ tg.setCharacter(termX, termY, '▄');
+ }
+ }
+
+ try {
+ screen.refresh(com.googlecode.lanterna.screen.Screen.RefreshType.COMPLETE);
+ } catch (IOException e) {
+ throw new RuntimeException(e);
+ }
+ }
+
+
+ private TextColor.RGB toColor(int rgb) {
+ int r = (rgb >> 16) & 0xFF;
+ int g = (rgb >> 8) & 0xFF;
+ int b = rgb & 0xFF;
+ return new TextColor.RGB(r, g, b);
+ }
+
+ @Override
+ public void handleMouseAction(MouseAction event) {
+
+ }
+
+ @Override
+ public void handleKeyboardAction(KeyboardPressEvent event) {
+
+ }
+}
diff --git a/src/main/java/cz/jzitnik/screens/scenes/Scene.java b/src/main/java/cz/jzitnik/screens/scenes/Scene.java
index 3245e3f..c11ec1d 100644
--- a/src/main/java/cz/jzitnik/screens/scenes/Scene.java
+++ b/src/main/java/cz/jzitnik/screens/scenes/Scene.java
@@ -9,6 +9,8 @@ import cz.jzitnik.game.GameState;
import cz.jzitnik.screens.Screen;
import cz.jzitnik.utils.DependencyManager;
import cz.jzitnik.utils.events.EventManager;
+import lombok.AllArgsConstructor;
+import lombok.Getter;
public abstract class Scene extends Screen {
private final Screen[] parts;
@@ -26,8 +28,16 @@ public abstract class Scene extends Screen {
@InjectDependency
private EventManager eventManager;
- public enum OnEndAction {
- SWITCH_TO_GAME
+ public static class OnEndAction {
+ public static class SwitchToGame extends OnEndAction {}
+ public static class Repeat extends OnEndAction {}
+ public static class None extends OnEndAction {}
+
+ @Getter
+ @AllArgsConstructor
+ public static class SwitchToScreen extends OnEndAction {
+ private final Screen screen;
+ }
}
public Scene(Screen[] parts, OnEndAction onEndAction) {
@@ -41,6 +51,8 @@ public abstract class Scene extends Screen {
if (!isRenderedAlready) {
isRenderedAlready = true;
render();
+ } else if (currentPart != null && !onEndAction.getClass().equals(OnEndAction.Repeat.class)) {
+ currentPart.fullRender();
}
}
@@ -52,18 +64,28 @@ public abstract class Scene extends Screen {
try {
currentPart = parts[++currentIndex];
} catch (ArrayIndexOutOfBoundsException e) {
- currentPart = null;
+ if (!onEndAction.getClass().equals(OnEndAction.Repeat.class)) {
+ currentPart = null;
+ } else {
+ break;
+ }
}
}
- switch (onEndAction) {
- case SWITCH_TO_GAME -> {
- gameState.setScreen(null);
- eventManager.emitEvent(new FullRoomDraw(true));
- }
+ if (onEndAction.getClass().equals(OnEndAction.SwitchToGame.class)) {
+ switchToGame();
+ } else if (onEndAction.getClass().equals(OnEndAction.SwitchToScreen.class)) {
+ OnEndAction.SwitchToScreen switchToScreen = (OnEndAction.SwitchToScreen) onEndAction;
+ gameState.setScreen(switchToScreen.getScreen());
+ eventManager.emitEvent(new FullRoomDraw(true));
}
}
+ protected void switchToGame() {
+ gameState.setScreen(null);
+ eventManager.emitEvent(new FullRoomDraw(true));
+ }
+
@Override
public void handleMouseAction(MouseAction event) {
currentPart.handleMouseAction(event);
diff --git a/src/main/resources/audio/menu.ogg b/src/main/resources/audio/menu.ogg
new file mode 100644
index 0000000..50369b3
Binary files /dev/null and b/src/main/resources/audio/menu.ogg differ
diff --git a/src/main/resources/menu.png b/src/main/resources/menu.png
new file mode 100644
index 0000000..9b53242
Binary files /dev/null and b/src/main/resources/menu.png differ