From 5127b9ee5f2fc88ebc00685952b6f7922fcb4475 Mon Sep 17 00:00:00 2001 From: jzitnik-dev Date: Tue, 18 Feb 2025 06:38:10 +0100 Subject: [PATCH] feat: Mouse events --- src/main/java/cz/jzitnik/Main.java | 35 +++++++++- src/main/java/cz/jzitnik/game/Game.java | 67 ++++++++++++++++++- .../cz/jzitnik/game/sprites/Breaking.java | 25 +++++++ src/main/resources/textures/breaking/1.ans | 26 +++++++ 4 files changed, 149 insertions(+), 4 deletions(-) create mode 100644 src/main/java/cz/jzitnik/game/sprites/Breaking.java create mode 100644 src/main/resources/textures/breaking/1.ans diff --git a/src/main/java/cz/jzitnik/Main.java b/src/main/java/cz/jzitnik/Main.java index 6084c7b..fe5e387 100644 --- a/src/main/java/cz/jzitnik/Main.java +++ b/src/main/java/cz/jzitnik/Main.java @@ -13,17 +13,42 @@ public class Main { try { // Set up terminal with JLine Terminal terminal = TerminalBuilder.terminal(); - terminal.enterRawMode(); // Switch to raw mode to capture keys immediately + terminal.enterRawMode(); var spriteList = SpriteLoader.load(); var screenRenderer = new ScreenRenderer(spriteList); var game = new Game(); final boolean[] isRunning = {true}; + // Enable mouse tracking + terminal.writer().print("\033[?1003h\n"); // Enable mouse move events + terminal.writer().flush(); + Thread inputThread = new Thread(() -> { try { while (isRunning[0]) { int key = terminal.reader().read(); + + // Check for mouse event sequence + if (key == 27) { // ESC + key = terminal.reader().read(); + if (key == '[') { + key = terminal.reader().read(); + if (key == 'M') { + int buttonCode = terminal.reader().read() - 32; + int x = terminal.reader().read() - 32; + int y = terminal.reader().read() - 32; + + if (buttonCode == 0) { + game.handleMouseClick(x, y); + throw new RuntimeException("sad"); + //screenRenderer.render(game.getWorld()); + } + } + } + } + + // Handle keyboard input as before switch (key) { case 'a': game.movePlayerLeft(screenRenderer); @@ -38,7 +63,7 @@ public class Main { screenRenderer.render(game.getWorld()); break; case 'm': - System.out.println("Mine pressed"); + game.mine(screenRenderer); break; case 'q': System.out.println("Exiting game..."); @@ -59,12 +84,16 @@ public class Main { while (isRunning[0]) { screenRenderer.render(game.getWorld()); try { - Thread.sleep(1000); // Control game loop speed + Thread.sleep(1000); } catch (InterruptedException e) { e.printStackTrace(); } } + // Disable mouse tracking on exit + terminal.writer().print("\033[?1003l\n"); + terminal.writer().flush(); + terminal.close(); } catch (IOException e) { e.printStackTrace(); diff --git a/src/main/java/cz/jzitnik/game/Game.java b/src/main/java/cz/jzitnik/game/Game.java index 1c0abcc..7891e9c 100644 --- a/src/main/java/cz/jzitnik/game/Game.java +++ b/src/main/java/cz/jzitnik/game/Game.java @@ -1,5 +1,6 @@ package cz.jzitnik.game; +import cz.jzitnik.game.sprites.Breaking; import cz.jzitnik.tui.ScreenRenderer; import lombok.Getter; import java.util.ArrayList; @@ -9,6 +10,7 @@ import java.util.List; public class Game { private List[][] world = new ArrayList[50][50]; private Block player; + private boolean mining; public Game() { for (int i = 0; i < 50; i++) { @@ -147,4 +149,67 @@ public class Game { } }).start(); } -} + + public void mine(ScreenRenderer screenRenderer) { + int[] cords = getPlayerCords(); + + if (world[cords[1] + 1][cords[0]].stream().allMatch(Block::isGhost)) { + return; + } + + world[cords[1] + 1][cords[0]].clear(); + world[cords[1] + 1][cords[0]].add(new Block("air", SpriteLoader.SPRITES.AIR, true)); + screenRenderer.render(world); + + new Thread(() -> { + try { + Thread.sleep(500); + } catch (InterruptedException e) { + throw new RuntimeException(e); + } + int[] cords2 = getPlayerCords(); + + if (world[cords2[1] + 1][cords2[0]].stream().anyMatch(Block::isGhost)) { + world[cords2[1] + 1][cords2[0]].add(player); + world[cords2[1]][cords2[0]].remove(player); + + screenRenderer.render(world); + } + }).start(); + } + + public void handleMouseClick(int mouseX, int mouseY) { + int[] cords = getPlayerCords(); + if (cords == null) return; + + int playerX = cords[0]; + int playerY = cords[1]; + int viewXRadius = 5; + int viewUpRadius = 4; + int viewDownRadius = 3; + + // Calculate visible area boundaries + int startX = Math.max(0, playerX - viewXRadius); + int endX = Math.min(world[0].length, playerX + viewXRadius + 1); + int startY = Math.max(0, playerY - viewUpRadius); + int endY = Math.min(world.length, playerY + viewDownRadius + 1); + + // Convert mouse coordinates to world coordinates + int blockX = startX + (mouseX / 50); // 50 chars wide per sprite + int blockY = startY + (mouseY / 25); // 25 lines high per sprite + + // Check if within bounds + if (blockY >= startY && blockY < endY && blockX >= startX && blockX < endX) { + List blocks = world[blockY][blockX]; + if (!blocks.isEmpty()) { + Block topBlock = blocks.get(blocks.size() - 1); // Get topmost block + System.out.println("Mouse clicked on block: " + topBlock.getBlockId() + + " at World Coordinates: [" + blockX + ", " + blockY + "]"); + } else { + System.out.println("No block at the clicked position."); + } + } else { + System.out.println("Clicked outside the visible area."); + } + } +} \ No newline at end of file diff --git a/src/main/java/cz/jzitnik/game/sprites/Breaking.java b/src/main/java/cz/jzitnik/game/sprites/Breaking.java new file mode 100644 index 0000000..4231a50 --- /dev/null +++ b/src/main/java/cz/jzitnik/game/sprites/Breaking.java @@ -0,0 +1,25 @@ +package cz.jzitnik.game.sprites; + +import cz.jzitnik.tui.ResourceLoader; +import cz.jzitnik.tui.Sprite; + +public class Breaking extends Sprite { + enum BreakingState { + FIRST, + SECOND, + THIRD + } + + public String getSprite() { + return ResourceLoader.loadResource("breaking/1.ans"); + } + + public String getSprite(Enum key) { + return ResourceLoader.loadResource(switch (key) { + case BreakingState.FIRST -> "breaking/1.ans"; + case BreakingState.SECOND -> "breaking/2.ans"; + case BreakingState.THIRD -> "breaking/3.ans"; + default -> throw new IllegalStateException("Unexpected value: " + key); + }); + } +} diff --git a/src/main/resources/textures/breaking/1.ans b/src/main/resources/textures/breaking/1.ans new file mode 100644 index 0000000..b0e6f07 --- /dev/null +++ b/src/main/resources/textures/breaking/1.ans @@ -0,0 +1,26 @@ +                                                   +                                                   +                                                   +                                                   +                                                   +                                                   +                                                   +                             ▓▓▓                   +                             ▓▓▓                   +                             ▓▓▓                   +             ▓▓▒             ▓▓▓▓▓▓▓▓▓             +         ░░░ ▓▓░             ▓▓▓▓▓▓▓▓▓             +         ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓             +         ▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓                   +         ▒▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓▓                   +                   ▓▓▓                             +                   ▓▓▓                             +                   ▓▓▓                             +                   ▓▓▓                             +                                                   +                                                   +                                                   +                                                   +                                                   +                                                   + \ No newline at end of file