forked from jzitnik/twodcraft
feat: Implemented falling trees
This commit is contained in:
parent
70c77cb5fb
commit
527cc0cf50
@ -0,0 +1,90 @@
|
|||||||
|
package cz.jzitnik.game.logic.services.leaves;
|
||||||
|
|
||||||
|
import cz.jzitnik.game.Game;
|
||||||
|
import cz.jzitnik.game.annotations.CustomLogic;
|
||||||
|
import cz.jzitnik.game.entities.Block;
|
||||||
|
import cz.jzitnik.game.logic.CustomLogicInterface;
|
||||||
|
|
||||||
|
import java.util.*;
|
||||||
|
|
||||||
|
@CustomLogic
|
||||||
|
public class LeavesFallingLogic implements CustomLogicInterface {
|
||||||
|
private static final int RADIUS = 30;
|
||||||
|
private final Random random = new Random();
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void nextIteration(Game game) {
|
||||||
|
int[] data = game.getPlayerCords();
|
||||||
|
var world = game.getWorld();
|
||||||
|
int playerX = data[0];
|
||||||
|
int playerY = data[1];
|
||||||
|
|
||||||
|
int startX = Math.max(0, playerX - RADIUS);
|
||||||
|
int startY = Math.max(0, playerY - RADIUS);
|
||||||
|
int endX = Math.min(world[0].length - 1, playerX + RADIUS);
|
||||||
|
int endY = Math.min(world.length - 1, playerY + RADIUS);
|
||||||
|
|
||||||
|
Set<String> supportedLeaves = findSupportedLeaves(world, startX, startY, endX, endY);
|
||||||
|
List<int[]> fallingLeaves = new ArrayList<>();
|
||||||
|
|
||||||
|
for (int x = startX; x <= endX; x++) {
|
||||||
|
for (int y = startY; y <= endY; y++) {
|
||||||
|
List<Block> blocks = world[y][x];
|
||||||
|
if (blocks.stream().anyMatch(block -> block.getBlockId().equals("oak_leaves"))) {
|
||||||
|
String key = x + "," + y;
|
||||||
|
if (!supportedLeaves.contains(key)) {
|
||||||
|
fallingLeaves.add(new int[]{x, y});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!fallingLeaves.isEmpty() && random.nextInt(4) < 1) {
|
||||||
|
int[] leafToRemove = fallingLeaves.get(random.nextInt(fallingLeaves.size()));
|
||||||
|
int leafX = leafToRemove[0];
|
||||||
|
int leafY = leafToRemove[1];
|
||||||
|
|
||||||
|
world[leafY][leafX].removeIf(block -> block.getBlockId().equals("oak_leaves"));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Set<String> findSupportedLeaves(List<Block>[][] world, int startX, int startY, int endX, int endY) {
|
||||||
|
Set<String> supportedLeaves = new HashSet<>();
|
||||||
|
Queue<int[]> queue = new LinkedList<>();
|
||||||
|
|
||||||
|
for (int x = startX; x <= endX; x++) {
|
||||||
|
for (int y = startY; y <= endY; y++) {
|
||||||
|
List<Block> blocks = world[y][x];
|
||||||
|
if (blocks.stream().anyMatch(block -> block.getBlockId().equals("oak_log"))) {
|
||||||
|
queue.add(new int[]{x, y});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int[][] directions = {{0,1}, {1,0}, {0,-1}, {-1,0}, {-1,1}, {1,1}, {-1,-1}, {1,-1}};
|
||||||
|
|
||||||
|
while (!queue.isEmpty()) {
|
||||||
|
int[] pos = queue.poll();
|
||||||
|
int cx = pos[0];
|
||||||
|
int cy = pos[1];
|
||||||
|
|
||||||
|
for (int[] dir : directions) {
|
||||||
|
int nx = cx + dir[0];
|
||||||
|
int ny = cy + dir[1];
|
||||||
|
|
||||||
|
if (nx >= startX && nx <= endX && ny >= startY && ny <= endY) {
|
||||||
|
List<Block> neighborBlocks = world[ny][nx];
|
||||||
|
if (neighborBlocks.stream().anyMatch(block -> block.getBlockId().equals("oak_leaves"))) {
|
||||||
|
String key = nx + "," + ny;
|
||||||
|
if (!supportedLeaves.contains(key)) {
|
||||||
|
supportedLeaves.add(key);
|
||||||
|
queue.add(new int[]{nx, ny});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return supportedLeaves;
|
||||||
|
}
|
||||||
|
}
|
Loading…
x
Reference in New Issue
Block a user