develop-turtleGame #6
@@ -7,10 +7,7 @@ import net.kyori.adventure.text.Component;
|
|||||||
import net.minestom.server.MinecraftServer;
|
import net.minestom.server.MinecraftServer;
|
||||||
import net.minestom.server.coordinate.Pos;
|
import net.minestom.server.coordinate.Pos;
|
||||||
import net.minestom.server.coordinate.Vec;
|
import net.minestom.server.coordinate.Vec;
|
||||||
import net.minestom.server.entity.Entity;
|
import net.minestom.server.entity.*;
|
||||||
import net.minestom.server.entity.EntityCreature;
|
|
||||||
import net.minestom.server.entity.EntityType;
|
|
||||||
import net.minestom.server.entity.Player;
|
|
||||||
import net.minestom.server.entity.attribute.Attribute;
|
import net.minestom.server.entity.attribute.Attribute;
|
||||||
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
import net.minestom.server.entity.metadata.other.FallingBlockMeta;
|
||||||
import net.minestom.server.event.player.PlayerTickEvent;
|
import net.minestom.server.event.player.PlayerTickEvent;
|
||||||
@@ -18,20 +15,21 @@ import net.minestom.server.instance.block.Block;
|
|||||||
import net.minestom.server.item.ItemStack;
|
import net.minestom.server.item.ItemStack;
|
||||||
import net.minestom.server.item.Material;
|
import net.minestom.server.item.Material;
|
||||||
import org.jetbrains.annotations.NotNull;
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
import java.util.concurrent.CompletableFuture;
|
import java.util.concurrent.CompletableFuture;
|
||||||
|
|
||||||
class TurtleGame extends StatelessGame {
|
class TurtleGame extends StatelessGame {
|
||||||
private final boolean firstPerson;
|
|
||||||
private final int radius;
|
private final int radius;
|
||||||
private final Map<Player, EntityCreature> turtlePlayerMap = new WeakHashMap<>();
|
private final Map<Player, EntityCreature> turtlePlayerMap = new WeakHashMap<>();
|
||||||
|
private final Map<Player, Integer> scoreMap = new WeakHashMap<>();
|
||||||
private final ArrayList<Entity> snacks = new ArrayList<>();
|
private final ArrayList<Entity> snacks = new ArrayList<>();
|
||||||
private final double speed = 2;
|
private final ArrayList<Entity> bombs = new ArrayList<>();
|
||||||
|
private double speed = 2;
|
||||||
|
|
||||||
public TurtleGame(boolean firstPerson, int radius) {
|
public TurtleGame(int radius) {
|
||||||
super(Dimension.OVERWORLD.key, "Turtle Game", new PointsWinScore());
|
super(Dimension.OVERWORLD.key, "Turtle Game", new PointsWinScore());
|
||||||
this.firstPerson = firstPerson;
|
|
||||||
this.radius = radius;
|
this.radius = radius;
|
||||||
|
|
||||||
this.eventNode()
|
this.eventNode()
|
||||||
@@ -60,20 +58,39 @@ class TurtleGame extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
protected void onPlayerTick(@NotNull PlayerTickEvent event) {
|
protected void onPlayerTick(@NotNull PlayerTickEvent event) {
|
||||||
EntityCreature turtle = this.turtlePlayerMap.get(event.getPlayer());
|
Player p = event.getPlayer();
|
||||||
turtle.teleport(turtle.getPosition().withView(event.getPlayer().getPosition()));
|
if(p.getGameMode() == GameMode.SPECTATOR) return;
|
||||||
Vec direction = event.getPlayer().getPosition().direction();
|
EntityCreature turtle = this.turtlePlayerMap.get(p);
|
||||||
|
turtle.teleport(turtle.getPosition().withView(p.getPosition()));
|
||||||
|
Vec direction = p.getPosition().direction();
|
||||||
if(this.isRunning()) {
|
if(this.isRunning()) {
|
||||||
Vec targetDirection = direction.withY(0).normalize().mul(this.speed);
|
Vec targetDirection = direction.withY(0).normalize().mul(this.speed);
|
||||||
turtle.setVelocity(targetDirection);
|
turtle.setVelocity(targetDirection);
|
||||||
|
|
||||||
List<Entity> hit = this.snacks.stream()
|
List<Entity> hitSnacks = this.snacks.stream()
|
||||||
.filter(snack -> snack.getBoundingBox().intersectBox(turtle.getPosition().sub(snack.getPosition()), turtle.getBoundingBox()))
|
.filter(snack -> snack.getBoundingBox().intersectBox(turtle.getPosition().sub(snack.getPosition()), turtle.getBoundingBox()))
|
||||||
.toList();
|
.toList();
|
||||||
hit.forEach(snack -> {
|
List<Entity> hitBombs = this.bombs.stream()
|
||||||
|
.filter(bomb -> bomb.getBoundingBox().intersectBox(turtle.getPosition().sub(bomb.getPosition()), turtle.getBoundingBox()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
hitSnacks.forEach(snack -> {
|
||||||
this.snacks.remove(snack);
|
this.snacks.remove(snack);
|
||||||
snack.remove();
|
snack.remove();
|
||||||
this.generateNewSnack();
|
this.generateNewSnack();
|
||||||
|
this.scoreMap.put(p, this.scoreMap.get(p) + 1);
|
||||||
|
});
|
||||||
|
hitBombs.forEach(bomb -> {
|
||||||
|
p.setGameMode(GameMode.SPECTATOR);
|
||||||
|
p.setFlying(true);
|
||||||
|
turtle.removePassenger(p);
|
||||||
|
turtle.remove();
|
||||||
|
turtle.kill();
|
||||||
|
this.bombs.remove(bomb);
|
||||||
|
bomb.remove();
|
||||||
|
this.generateNewBomb();
|
||||||
|
this.getScore().insertResult(p, this.scoreMap.get(p));
|
||||||
|
this.speed += 0.5;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -86,6 +103,7 @@ class TurtleGame extends StatelessGame {
|
|||||||
EntityCreature turtle = new EntityCreature(EntityType.TURTLE);
|
EntityCreature turtle = new EntityCreature(EntityType.TURTLE);
|
||||||
this.turtlePlayerMap.put(p, turtle);
|
this.turtlePlayerMap.put(p, turtle);
|
||||||
}
|
}
|
||||||
|
this.scoreMap.putIfAbsent(p, 0);
|
||||||
|
|
||||||
EntityCreature turtle = this.turtlePlayerMap.get(p);
|
EntityCreature turtle = this.turtlePlayerMap.get(p);
|
||||||
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
|
MinecraftServer.getSchedulerManager().scheduleNextTick(() -> {
|
||||||
@@ -116,38 +134,67 @@ class TurtleGame extends StatelessGame {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private void generateNewSnack() {
|
private void generateNewSnack() {
|
||||||
Pos spawnPosition;
|
|
||||||
boolean isInRadius, collides;
|
|
||||||
int counter = 0;
|
|
||||||
Entity snack = new Entity(EntityType.FALLING_BLOCK);
|
Entity snack = new Entity(EntityType.FALLING_BLOCK);
|
||||||
FallingBlockMeta meta = (FallingBlockMeta) snack.getEntityMeta();
|
FallingBlockMeta meta = (FallingBlockMeta) snack.getEntityMeta();
|
||||||
meta.setBlock(Block.CHORUS_FLOWER);
|
meta.setBlock(Block.SUNFLOWER.withProperty("half", "upper"));
|
||||||
snack.setInstance(this);
|
snack.setInstance(this);
|
||||||
|
Pos spawnPosition = this.newSpawnPosition(snack);
|
||||||
do {
|
if(spawnPosition == null) {
|
||||||
if(counter > 200) {
|
|
||||||
snack.remove();
|
snack.remove();
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
snack.teleport(spawnPosition);
|
||||||
|
this.snacks.add(snack);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void generateNewBomb() {
|
||||||
|
Entity bomb = new Entity(EntityType.FALLING_BLOCK);
|
||||||
|
FallingBlockMeta meta = (FallingBlockMeta) bomb.getEntityMeta();
|
||||||
|
meta.setBlock(Block.TNT);
|
||||||
|
bomb.setInstance(this);
|
||||||
|
Pos spawnPosition = this.newSpawnPosition(bomb, 2);
|
||||||
|
if(spawnPosition == null) {
|
||||||
|
bomb.remove();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
bomb.teleport(spawnPosition);
|
||||||
|
this.bombs.add(bomb);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Pos newSpawnPosition(Entity entity) {
|
||||||
|
return this.newSpawnPosition(entity, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Nullable
|
||||||
|
private Pos newSpawnPosition(Entity entity, double border) {
|
||||||
|
Pos spawnPosition;
|
||||||
|
int counter = 0;
|
||||||
|
boolean isInRadius, collides;
|
||||||
|
do {
|
||||||
|
if(counter > 200) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
int x = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
int x = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
||||||
int z = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
int z = this.rnd.nextInt(-this.radius+2, this.radius-2);
|
||||||
spawnPosition = new Pos(x, 1, z).add(0.5, 0, 0.5);
|
spawnPosition = new Pos(x, 1, z).add(0.5, 0, 0.5);
|
||||||
Pos checkPosition = spawnPosition;
|
Pos checkPosition = spawnPosition;
|
||||||
isInRadius = checkPosition.distance(0, 1, 0) < this.radius-3;
|
isInRadius = checkPosition.distance(0, 1, 0) < this.radius-3;
|
||||||
collides = this.getEntities().stream()
|
collides = this.getEntities().stream()
|
||||||
.filter(entity -> !entity.equals(snack))
|
.filter(e -> !e.equals(entity))
|
||||||
.anyMatch(entity -> snack.getBoundingBox().intersectBox(entity.getPosition().sub(checkPosition), entity.getBoundingBox()));
|
.anyMatch(e -> entity.getBoundingBox().growSymmetrically(border, border, border).intersectBox(e.getPosition().sub(checkPosition), e.getBoundingBox()));
|
||||||
counter++;
|
counter++;
|
||||||
} while (!isInRadius || collides);
|
} while (!isInRadius || collides);
|
||||||
Pupsi marked this conversation as resolved
Outdated
|
|||||||
|
return spawnPosition;
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
default color ist nicht weiß? default color ist nicht weiß?
|
|||||||
snack.teleport(spawnPosition);
|
|
||||||
this.snacks.add(snack);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
protected void onStart() {
|
protected void onStart() {
|
||||||
for (int i = 0; i < 100; i++) {
|
for (int i = 0; i < 10; i++) {
|
||||||
this.generateNewSnack();
|
this.generateNewSnack();
|
||||||
}
|
}
|
||||||
|
for (int i = 0; i < 5; i++) {
|
||||||
Pupsi marked this conversation as resolved
Outdated
MineTec
commented
statt teleport direkt bei setInstance als zweiter Parameter die Position übergeben statt teleport direkt bei setInstance als zweiter Parameter die Position übergeben
|
|||||||
|
this.generateNewBomb();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@@ -4,7 +4,6 @@ import eu.mhsl.minenet.minigames.instance.game.Game;
|
|||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.ConfigManager;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.GameFactory;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.Option;
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.BoolOption;
|
|
||||||
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
|
import eu.mhsl.minenet.minigames.instance.game.stateless.config.common.NumericOption;
|
||||||
import eu.mhsl.minenet.minigames.instance.room.Room;
|
import eu.mhsl.minenet.minigames.instance.room.Room;
|
||||||
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
import eu.mhsl.minenet.minigames.message.component.TranslatedComponent;
|
||||||
@@ -27,13 +26,12 @@ public class TurtleGameFactory implements GameFactory {
|
|||||||
@Override
|
@Override
|
||||||
public ConfigManager configuration() {
|
public ConfigManager configuration() {
|
||||||
return new ConfigManager()
|
return new ConfigManager()
|
||||||
.addOption(new BoolOption("firstPerson", Material.SPYGLASS, TranslatedComponent.byId("game_TurtleGame#firstPerson")))
|
|
||||||
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30, 40));
|
.addOption(new NumericOption("radius", Material.HEART_OF_THE_SEA, TranslatedComponent.byId("optionCommon#radius"), 10, 20, 30, 40));
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
public Game manufacture(Room parent, Map<String, Option<?>> configuration) throws Exception {
|
||||||
return new TurtleGame(configuration.get("firstPerson").getAsBoolean(), configuration.get("radius").getAsInt());
|
return new TurtleGame(configuration.get("radius").getAsInt());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
Reference in New Issue
Block a user
property doppelt sich?