feat(gameplay): Added day-night cycle
This commit is contained in:
parent
ca98fe7fae
commit
8b09d71a44
@ -45,6 +45,8 @@ public class Game extends AutoTransientSupport {
|
||||
private transient EntitySpawnProvider entitySpawnProvider = new EntitySpawnProvider();
|
||||
@AutoTransient
|
||||
private transient GameStates gameStates = new GameStates(this);
|
||||
@Setter
|
||||
private int daytime = 0; // 0-600
|
||||
|
||||
public Game() {
|
||||
Generation.generateWorld(this);
|
||||
|
@ -26,6 +26,7 @@ public class DefaultPlaceHandler implements CustomPlaceHandler {
|
||||
public boolean mine(Game game, int x, int y) {
|
||||
var blocks = game.getWorld()[y][x];
|
||||
|
||||
log.info("Block was mined at coordinates x:{},y:{}", x, y);
|
||||
blocks.removeAll(blocks.stream().filter(i -> !i.getBlockId().equals("air") && !i.isMob()).toList());
|
||||
|
||||
return true;
|
||||
|
@ -6,8 +6,11 @@ import java.util.List;
|
||||
import java.util.Set;
|
||||
|
||||
import cz.jzitnik.game.annotations.*;
|
||||
import lombok.extern.slf4j.Slf4j;
|
||||
|
||||
import org.reflections.Reflections;
|
||||
|
||||
@Slf4j
|
||||
public class PlaceHandler {
|
||||
private final HashMap<String, CustomPlaceHandler> placeHandlerList = new HashMap<>();
|
||||
private final CustomPlaceHandler defaultPlaceHandler = new DefaultPlaceHandler();
|
||||
@ -26,7 +29,10 @@ public class PlaceHandler {
|
||||
return defaultPlaceHandler;
|
||||
}
|
||||
|
||||
return placeHandlerList.get(itemId);
|
||||
var placeHandler = placeHandlerList.get(itemId);
|
||||
|
||||
log.debug("Using {} to mine/place a block", placeHandler.getClass().getSimpleName());
|
||||
return placeHandler;
|
||||
}
|
||||
|
||||
public PlaceHandler() {
|
||||
|
@ -0,0 +1,19 @@
|
||||
package cz.jzitnik.game.logic.services.daytime;
|
||||
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.annotations.CustomLogic;
|
||||
import cz.jzitnik.game.logic.CustomLogicInterface;
|
||||
|
||||
@CustomLogic
|
||||
public class DayTimeLogic implements CustomLogicInterface {
|
||||
@Override
|
||||
public void nextIteration(Game game) {
|
||||
int time = game.getDaytime();
|
||||
|
||||
if (time >= 600) {
|
||||
game.setDaytime(0);
|
||||
} else {
|
||||
game.setDaytime(time + 1);
|
||||
}
|
||||
}
|
||||
}
|
@ -3,19 +3,29 @@ package cz.jzitnik.game.sprites;
|
||||
import cz.jzitnik.tui.Sprite;
|
||||
|
||||
public class Air extends Sprite {
|
||||
private String resource;
|
||||
|
||||
public Air() {
|
||||
StringBuilder sprite = new StringBuilder();
|
||||
for (int i = 0; i < 25; i++) {
|
||||
sprite.append("\033[48;2;121;166;255m ".repeat(50));
|
||||
sprite.append("\n");
|
||||
}
|
||||
resource = sprite.toString();
|
||||
public String getSprite() {
|
||||
throw new RuntimeException("Imposible state");
|
||||
}
|
||||
|
||||
public String getSprite() {
|
||||
return resource;
|
||||
public String getSprite(int daytime) {
|
||||
StringBuilder sprite = new StringBuilder();
|
||||
|
||||
// Normalize daytime to a range of 0 to 1, where 300 is the darkest
|
||||
double normalized = Math.abs((daytime - 300) / 300.0);
|
||||
|
||||
// Interpolate blue color intensity (darker at midday, brighter at
|
||||
// sunrise/sunset)
|
||||
int blue = (int) (255 * normalized);
|
||||
int red = (int) (121 * normalized);
|
||||
int green = (int) (166 * normalized);
|
||||
|
||||
String colorCode = String.format("\033[48;2;%d;%d;%dm ", red, green, blue);
|
||||
|
||||
for (int i = 0; i < 25; i++) {
|
||||
sprite.append(colorCode.repeat(50)).append("\n");
|
||||
}
|
||||
|
||||
return sprite.toString();
|
||||
}
|
||||
|
||||
public String getSprite(Enum e) {
|
||||
|
@ -2,6 +2,7 @@ package cz.jzitnik.tui;
|
||||
|
||||
import cz.jzitnik.game.entities.Block;
|
||||
import cz.jzitnik.game.Game;
|
||||
import cz.jzitnik.game.sprites.Air;
|
||||
import cz.jzitnik.game.sprites.SimpleSprite;
|
||||
import cz.jzitnik.game.sprites.Steve;
|
||||
import cz.jzitnik.game.blocks.Chest;
|
||||
@ -45,6 +46,19 @@ public class ScreenRenderer {
|
||||
return null;
|
||||
}
|
||||
|
||||
public String getTexture(Block block, SpriteList spriteList, Game game) {
|
||||
if (Air.class.isAssignableFrom(spriteList.getSprite(block.getSprite()).getClass())) {
|
||||
var air = (Air) spriteList.getSprite(block.getSprite());
|
||||
return air.getSprite(game.getDaytime());
|
||||
}
|
||||
|
||||
if (block.getSpriteState().isEmpty()) {
|
||||
return spriteList.getSprite(block.getSprite()).getSprite();
|
||||
}
|
||||
|
||||
return spriteList.getSprite(block.getSprite()).getSprite(block.getSpriteState().get());
|
||||
}
|
||||
|
||||
public synchronized void render(Game game) {
|
||||
log.debug("Rendering frame");
|
||||
var world = game.getWorld();
|
||||
@ -103,10 +117,7 @@ public class ScreenRenderer {
|
||||
for (int x = startX; x < endX; x++) {
|
||||
List<Block> blocks = world[y][x];
|
||||
List<String> sprites = new ArrayList<>(blocks.stream()
|
||||
.map(block -> block.getSpriteState().isEmpty()
|
||||
? spriteList.getSprite(block.getSprite()).getSprite()
|
||||
: spriteList.getSprite(block.getSprite())
|
||||
.getSprite(block.getSpriteState().get()))
|
||||
.map(block -> getTexture(block, spriteList, game))
|
||||
.toList());
|
||||
|
||||
if (selectedBlock.isPresent() && selectedBlock.get().get(0) == x
|
||||
|
Loading…
x
Reference in New Issue
Block a user