merge dev into test #33
@@ -1,5 +1,7 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="MdgaApp" type="Application" factoryName="Application" singleton="false" nameIsGenerated="true">
|
<configuration default="false" name="MdgaApp" type="Application" factoryName="Application" singleton="false" nameIsGenerated="true">
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH" value="temurin-20" />
|
||||||
|
<option name="ALTERNATIVE_JRE_PATH_ENABLED" value="true" />
|
||||||
<option name="MAIN_CLASS_NAME" value="pp.mdga.client.MdgaApp" />
|
<option name="MAIN_CLASS_NAME" value="pp.mdga.client.MdgaApp" />
|
||||||
<module name="Projekte.mdga.client.main" />
|
<module name="Projekte.mdga.client.main" />
|
||||||
<option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties -ea" />
|
<option name="VM_PARAMETERS" value="-Djava.util.logging.config.file=logging.properties -ea" />
|
||||||
@@ -14,4 +16,4 @@
|
|||||||
<option name="Make" enabled="true" />
|
<option name="Make" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
||||||
@@ -0,0 +1,48 @@
|
|||||||
|
package pp.mdga.client;
|
||||||
|
|
||||||
|
import com.jme3.renderer.RenderManager;
|
||||||
|
import com.jme3.renderer.ViewPort;
|
||||||
|
import com.jme3.scene.Spatial;
|
||||||
|
import com.jme3.scene.control.AbstractControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An abstract control class that serves as a base for initializing spatial objects
|
||||||
|
* in jMonkeyEngine. This class overrides the controlUpdate and controlRender methods
|
||||||
|
* from the AbstractControl class, providing default empty implementations,
|
||||||
|
* and adds the ability to initialize spatial objects when they are set.
|
||||||
|
*/
|
||||||
|
public abstract class InitControl extends AbstractControl {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
protected void controlRender(RenderManager rm, ViewPort vp) {
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the spatial object to be controlled. This method also initializes the spatial
|
||||||
|
* if it is being set for the first time.
|
||||||
|
*
|
||||||
|
* @param spatial The spatial object to control.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void setSpatial(Spatial spatial) {
|
||||||
|
if (this.spatial == null && spatial != null) {
|
||||||
|
super.setSpatial(spatial);
|
||||||
|
initSpatial();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the spatial object. This method can be overridden by subclasses
|
||||||
|
* to define custom initialization logic for the spatial.
|
||||||
|
* This method is called automatically when the spatial is set for the first time.
|
||||||
|
*/
|
||||||
|
protected void initSpatial() {
|
||||||
|
// Default empty implementation. Override to add initialization logic.
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,11 +17,13 @@
|
|||||||
import pp.mdga.client.board.OutlineControl;
|
import pp.mdga.client.board.OutlineControl;
|
||||||
import pp.mdga.client.board.PieceControl;
|
import pp.mdga.client.board.PieceControl;
|
||||||
import pp.mdga.client.gui.CardControl;
|
import pp.mdga.client.gui.CardControl;
|
||||||
|
import pp.mdga.client.gui.DiceControl;
|
||||||
import pp.mdga.client.view.GameView;
|
import pp.mdga.client.view.GameView;
|
||||||
import pp.mdga.game.BonusCard;
|
import pp.mdga.game.BonusCard;
|
||||||
import pp.mdga.game.Color;
|
import pp.mdga.game.Color;
|
||||||
import pp.mdga.game.Piece;
|
import pp.mdga.game.Piece;
|
||||||
import pp.mdga.notification.FinishNotification;
|
import pp.mdga.notification.FinishNotification;
|
||||||
|
import pp.mdga.notification.MovePieceNotification;
|
||||||
import pp.mdga.notification.SelectableCardsNotification;
|
import pp.mdga.notification.SelectableCardsNotification;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
@@ -92,10 +94,14 @@ public void onAction(String name, boolean isPressed, float tpf) {
|
|||||||
}
|
}
|
||||||
if(name.equals("Click") && isPressed) {
|
if(name.equals("Click") && isPressed) {
|
||||||
if (app.getView() instanceof GameView gameView) {
|
if (app.getView() instanceof GameView gameView) {
|
||||||
|
DiceControl diceSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), DiceControl.class);
|
||||||
CardControl cardLayerSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), CardControl.class);
|
CardControl cardLayerSelect = checkHover(gameView.getGuiHandler().getCardLayerCamera(), gameView.getGuiHandler().getCardLayerRootNode(), CardControl.class);
|
||||||
OutlineControl boardSelect = checkHover(app.getCamera(), app.getRootNode(), OutlineControl.class);
|
OutlineControl boardSelect = checkHover(app.getCamera(), app.getRootNode(), OutlineControl.class);
|
||||||
|
|
||||||
if(cardLayerSelect != null) {
|
if(diceSelect != null) {
|
||||||
|
app.getModelSynchronize().rolledDice();
|
||||||
|
}
|
||||||
|
else if(cardLayerSelect != null) {
|
||||||
//cardSelect
|
//cardSelect
|
||||||
if(cardLayerSelect.isSelectable()) gameView.getGuiHandler().selectCard(cardLayerSelect);
|
if(cardLayerSelect.isSelectable()) gameView.getGuiHandler().selectCard(cardLayerSelect);
|
||||||
}
|
}
|
||||||
@@ -117,7 +123,11 @@ else if(boardSelect != null) {
|
|||||||
}
|
}
|
||||||
if(name.equals("Test") &&isPressed){
|
if(name.equals("Test") &&isPressed){
|
||||||
if(app.getView() instanceof GameView gameView){
|
if(app.getView() instanceof GameView gameView){
|
||||||
app.getNotificationSynchronizer().addTestNotification(new FinishNotification(Color.NAVY));
|
// gameView.getGuiHandler().rollRankingResult(Color.AIRFORCE, 1);
|
||||||
|
// gameView.getGuiHandler().rollRankingResult(Color.ARMY, 2);
|
||||||
|
// gameView.getGuiHandler().rollRankingResult(Color.NAVY, 3);
|
||||||
|
// gameView.getGuiHandler().rollRankingResult(Color.CYBER, 4);
|
||||||
|
gameView.getGuiHandler().showDice();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,14 +1,11 @@
|
|||||||
package pp.mdga.client;
|
package pp.mdga.client;
|
||||||
|
|
||||||
import com.jme3.app.SimpleApplication;
|
import com.jme3.app.SimpleApplication;
|
||||||
import com.jme3.system.JmeContext;
|
import com.jme3.system.AppSettings;
|
||||||
import com.simsilica.lemur.GuiGlobals;
|
import com.simsilica.lemur.GuiGlobals;
|
||||||
import pp.mdga.client.acoustic.AcousticHandler;
|
import pp.mdga.client.acoustic.AcousticHandler;
|
||||||
import pp.mdga.client.animation.AnimationHandler;
|
|
||||||
import com.jme3.system.AppSettings;
|
|
||||||
import pp.mdga.client.dialog.JoinDialog;
|
import pp.mdga.client.dialog.JoinDialog;
|
||||||
import pp.mdga.client.view.*;
|
import pp.mdga.client.view.*;
|
||||||
import pp.mdga.message.server.ServerInterpreter;
|
|
||||||
|
|
||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.util.concurrent.ExecutorService;
|
import java.util.concurrent.ExecutorService;
|
||||||
@@ -23,9 +20,6 @@ public class MdgaApp extends SimpleApplication {
|
|||||||
|
|
||||||
private static Preferences prefs = Preferences.userNodeForPackage(JoinDialog.class);
|
private static Preferences prefs = Preferences.userNodeForPackage(JoinDialog.class);
|
||||||
|
|
||||||
/** Handles animations in the application. */
|
|
||||||
private AnimationHandler animationHandler;
|
|
||||||
|
|
||||||
/** Handles acoustic effects and state-based sounds. */
|
/** Handles acoustic effects and state-based sounds. */
|
||||||
private AcousticHandler acousticHandler;
|
private AcousticHandler acousticHandler;
|
||||||
|
|
||||||
@@ -88,6 +82,7 @@ public static void main(String[] args) {
|
|||||||
MdgaApp app = new MdgaApp();
|
MdgaApp app = new MdgaApp();
|
||||||
app.setSettings(settings);
|
app.setSettings(settings);
|
||||||
app.setShowSettings(false);
|
app.setShowSettings(false);
|
||||||
|
app.setPauseOnLostFocus(false);
|
||||||
app.start();
|
app.start();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -102,7 +97,6 @@ public void simpleInitApp() {
|
|||||||
|
|
||||||
flyCam.setEnabled(false);
|
flyCam.setEnabled(false);
|
||||||
|
|
||||||
animationHandler = new AnimationHandler(this);
|
|
||||||
acousticHandler = new AcousticHandler(this);
|
acousticHandler = new AcousticHandler(this);
|
||||||
notificationSynchronizer = new NotificationSynchronizer(this);
|
notificationSynchronizer = new NotificationSynchronizer(this);
|
||||||
inputSynchronizer = new InputSynchronizer(this);
|
inputSynchronizer = new InputSynchronizer(this);
|
||||||
@@ -163,14 +157,6 @@ public void enter(MdgaState state) {
|
|||||||
view.enter();
|
view.enter();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the animation handler.
|
|
||||||
*
|
|
||||||
* @return the {@link AnimationHandler} instance
|
|
||||||
*/
|
|
||||||
public AnimationHandler getAnimationHandler() {
|
|
||||||
return animationHandler;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the acoustic handler.
|
* Gets the acoustic handler.
|
||||||
|
|||||||
@@ -107,8 +107,8 @@ public void selectTsk(Color color) {
|
|||||||
app.getGameLogic().selectTsk(color);
|
app.getGameLogic().selectTsk(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void unselectTsk() {
|
public void unselectTsk(Color color) {
|
||||||
app.getGameLogic().selectTsk(Color.NONE);
|
app.getGameLogic().deselectTSK(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void rolledDice() {
|
public void rolledDice() {
|
||||||
|
|||||||
@@ -60,15 +60,15 @@ private void handleLobby(Notification notification) {
|
|||||||
|
|
||||||
if (notification instanceof TskSelectNotification n) {
|
if (notification instanceof TskSelectNotification n) {
|
||||||
lobbyView.setTaken(n.getColor(), true, n.isSelf(), n.getName());
|
lobbyView.setTaken(n.getColor(), true, n.isSelf(), n.getName());
|
||||||
lobbyView.setTaken(n.getColor(), true, false, n.getName());
|
|
||||||
} else if (notification instanceof StartDialogNotification) {
|
} else if (notification instanceof StartDialogNotification) {
|
||||||
app.enter(MdgaState.MAIN);
|
app.enter(MdgaState.MAIN);
|
||||||
} else if (notification instanceof TskUnselectNotification n) {
|
} else if (notification instanceof TskUnselectNotification n) {
|
||||||
lobbyView.setTaken(n.getColor(), false, false, null);
|
lobbyView.setTaken(n.getColor(), false, false, null);
|
||||||
} else if(notification instanceof LobbyReadyNotification lobbyReadyNotification) {
|
} else if(notification instanceof LobbyReadyNotification lobbyReadyNotification) {
|
||||||
lobbyView.setReady(lobbyReadyNotification.getColor(), lobbyReadyNotification.isReady());
|
lobbyView.setReady(lobbyReadyNotification.getColor(), lobbyReadyNotification.isReady());
|
||||||
} else if (notification instanceof GameNotification) {
|
} else if (notification instanceof GameNotification n) {
|
||||||
app.enter(MdgaState.GAME);
|
app.enter(MdgaState.GAME);
|
||||||
|
((GameView) app.getView()).setOwnColor(n.getOwnColor());
|
||||||
} else {
|
} else {
|
||||||
throw new RuntimeException("notification not expected: " + notification.toString());
|
throw new RuntimeException("notification not expected: " + notification.toString());
|
||||||
}
|
}
|
||||||
@@ -84,6 +84,7 @@ private void handleGame(Notification notification) {
|
|||||||
guiHandler.addCard(n.getBonusCard());
|
guiHandler.addCard(n.getBonusCard());
|
||||||
} else if (notification instanceof ActivePlayerNotification n) {
|
} else if (notification instanceof ActivePlayerNotification n) {
|
||||||
gameView.getGuiHandler().setActivePlayer(n.getColor());
|
gameView.getGuiHandler().setActivePlayer(n.getColor());
|
||||||
|
boardHandler.showDice(n.getColor());
|
||||||
} else if (notification instanceof CeremonyNotification ceremonyNotification) {
|
} else if (notification instanceof CeremonyNotification ceremonyNotification) {
|
||||||
app.enter(MdgaState.CEREMONY);
|
app.enter(MdgaState.CEREMONY);
|
||||||
CeremonyView ceremonyView = (CeremonyView) app.getView();
|
CeremonyView ceremonyView = (CeremonyView) app.getView();
|
||||||
@@ -116,22 +117,22 @@ private void handleGame(Notification notification) {
|
|||||||
} else if (notification instanceof DrawCardNotification n) {
|
} else if (notification instanceof DrawCardNotification n) {
|
||||||
guiHandler.drawCard(n.getColor());
|
guiHandler.drawCard(n.getColor());
|
||||||
} else if (notification instanceof HomeMoveNotification home) {
|
} else if (notification instanceof HomeMoveNotification home) {
|
||||||
boardHandler.moveHomePiece(home.getPieceId(), home.getHomeIndex());
|
boardHandler.movePieceHomeAnim(home.getPieceId(), home.getHomeIndex());
|
||||||
guiHandler.hideText();
|
guiHandler.hideText();
|
||||||
} else if (notification instanceof InterruptNotification) {
|
} else if (notification instanceof InterruptNotification) {
|
||||||
app.enter(MdgaState.LOBBY);
|
app.enter(MdgaState.LOBBY);
|
||||||
} else if (notification instanceof MovePieceNotification n) {
|
} else if (notification instanceof MovePieceNotification n) {
|
||||||
if(n.isMoveStart()) {
|
if(n.isMoveStart()) {
|
||||||
//StartMove
|
//StartMove
|
||||||
boardHandler.movePieceStart(n.getPiece(), n.getMoveIndex());
|
boardHandler.movePieceStartAnim(n.getPiece(), n.getMoveIndex());
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
//InfieldMove
|
//InfieldMove
|
||||||
boardHandler.movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
|
boardHandler.movePieceAnim(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
|
||||||
}
|
}
|
||||||
guiHandler.hideText();
|
guiHandler.hideText();
|
||||||
} else if (notification instanceof ThrowPieceNotification n) {
|
} else if (notification instanceof ThrowPieceNotification n) {
|
||||||
boardHandler.throwPiece(n.getPieceId());
|
boardHandler.throwPieceAnim(n.getPieceId());
|
||||||
} else if (notification instanceof NoShieldNotification n) {
|
} else if (notification instanceof NoShieldNotification n) {
|
||||||
boardHandler.unshieldPiece(n.getPieceId());
|
boardHandler.unshieldPiece(n.getPieceId());
|
||||||
} else if (notification instanceof PlayCardNotification n) {
|
} else if (notification instanceof PlayCardNotification n) {
|
||||||
@@ -147,10 +148,12 @@ private void handleGame(Notification notification) {
|
|||||||
} else if (notification instanceof ResumeNotification) {
|
} else if (notification instanceof ResumeNotification) {
|
||||||
//TODO
|
//TODO
|
||||||
} else if (notification instanceof RollDiceNotification n) {
|
} else if (notification instanceof RollDiceNotification n) {
|
||||||
|
gameView.getGuiHandler().hideText();
|
||||||
if(n.getColor() == gameView.getOwnColor()){
|
if(n.getColor() == gameView.getOwnColor()){
|
||||||
guiHandler.rollDice(n.getEyes(), n.isTurbo() ? n.getMultiplier() : -1);
|
guiHandler.rollDice(n.getEyes(), n.isTurbo() ? n.getMultiplier() : -1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
|
boardHandler.hideDice();
|
||||||
if (n.isTurbo()) guiHandler.showRolledDiceMult(n.getEyes(), n.getMultiplier(), n.getColor());
|
if (n.isTurbo()) guiHandler.showRolledDiceMult(n.getEyes(), n.getMultiplier(), n.getColor());
|
||||||
else guiHandler.showRolledDice(n.getEyes(), n.getColor());
|
else guiHandler.showRolledDice(n.getEyes(), n.getColor());
|
||||||
}
|
}
|
||||||
@@ -163,7 +166,7 @@ private void handleGame(Notification notification) {
|
|||||||
} else if (notification instanceof StartDialogNotification) {
|
} else if (notification instanceof StartDialogNotification) {
|
||||||
app.enter(MdgaState.MAIN);
|
app.enter(MdgaState.MAIN);
|
||||||
} else if (notification instanceof SwapPieceNotification n) {
|
} else if (notification instanceof SwapPieceNotification n) {
|
||||||
boardHandler.swapPieces(n.getFirstPiece(), n.getSecondPiece());
|
// boardHandler.swapPieces(n.getFirstPiece(), n.getSecondPiece());
|
||||||
guiHandler.swap();
|
guiHandler.swap();
|
||||||
} else if (notification instanceof WaitMoveNotification) {
|
} else if (notification instanceof WaitMoveNotification) {
|
||||||
//TODO ???
|
//TODO ???
|
||||||
|
|||||||
@@ -1,10 +0,0 @@
|
|||||||
package pp.mdga.client.animation;
|
|
||||||
|
|
||||||
abstract class Animation {
|
|
||||||
|
|
||||||
abstract void play();
|
|
||||||
|
|
||||||
abstract void stop();
|
|
||||||
|
|
||||||
abstract boolean isOver();
|
|
||||||
}
|
|
||||||
@@ -1,29 +0,0 @@
|
|||||||
package pp.mdga.client.animation;
|
|
||||||
|
|
||||||
import pp.mdga.client.MdgaApp;
|
|
||||||
|
|
||||||
public class AnimationHandler {
|
|
||||||
private MdgaApp app;
|
|
||||||
|
|
||||||
private Animation animation = null;
|
|
||||||
|
|
||||||
public AnimationHandler(MdgaApp app) {
|
|
||||||
this.app = app;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void playAnimation(MdgaAnimation type) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void update() {
|
|
||||||
if (null == animation) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (animation.isOver()) {
|
|
||||||
animation = null;
|
|
||||||
|
|
||||||
//trigger next state in model
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,18 +0,0 @@
|
|||||||
package pp.mdga.client.animation;
|
|
||||||
|
|
||||||
class EmptyAnimation extends Animation {
|
|
||||||
@Override
|
|
||||||
void play() {
|
|
||||||
//nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
void stop() {
|
|
||||||
//nothing
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
boolean isOver() {
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +0,0 @@
|
|||||||
package pp.mdga.client.animation;
|
|
||||||
|
|
||||||
public enum MdgaAnimation {
|
|
||||||
}
|
|
||||||
@@ -0,0 +1,109 @@
|
|||||||
|
package pp.mdga.client.animation;
|
||||||
|
|
||||||
|
import com.jme3.math.Vector3f;
|
||||||
|
import pp.mdga.client.InitControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A control that smoothly moves a spatial from an initial position to an end position
|
||||||
|
* using a quadratic interpolation, with the option to perform an action after the movement is complete.
|
||||||
|
* The movement path includes an intermediate "middle" position at a specified height.
|
||||||
|
*
|
||||||
|
* <p>Movement speed can be adjusted by modifying the MOVE_SPEED constant. The movement easing follows
|
||||||
|
* an ease-in-out curve to create a smooth start and stop effect.
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class MoveControl extends InitControl {
|
||||||
|
|
||||||
|
private boolean moving;
|
||||||
|
private final Vector3f initPos;
|
||||||
|
private final Vector3f endPos;
|
||||||
|
private final Vector3f middlePos;
|
||||||
|
private final static float HEIGHT = 2;
|
||||||
|
private final static float MOVE_SPEED = 1f;
|
||||||
|
private float progress = 0;
|
||||||
|
private final Runnable actionAfter;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new MoveControl with specified initial and end positions, and an action to run after the movement.
|
||||||
|
* The movement follows a path with a midpoint at a fixed height.
|
||||||
|
*
|
||||||
|
* @param initPos The starting position of the spatial.
|
||||||
|
* @param endPos The target position of the spatial.
|
||||||
|
* @param actionAfter A Runnable that will be executed after the movement finishes.
|
||||||
|
*/
|
||||||
|
public MoveControl(Vector3f initPos, Vector3f endPos, Runnable actionAfter){
|
||||||
|
moving = false;
|
||||||
|
this.initPos = initPos;
|
||||||
|
this.endPos = endPos;
|
||||||
|
middlePos = new Vector3f(
|
||||||
|
(initPos.x + endPos.x) / 2,
|
||||||
|
(initPos.y + endPos.y) / 2,
|
||||||
|
HEIGHT
|
||||||
|
);
|
||||||
|
this.actionAfter = actionAfter;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the movement by resetting the progress and setting the moving flag to true.
|
||||||
|
* This is called automatically when the spatial is set.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initSpatial() {
|
||||||
|
moving = true;
|
||||||
|
progress = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the movement of the spatial by interpolating its position along the defined path.
|
||||||
|
* The movement is smoothed using an easing function.
|
||||||
|
* Once the movement reaches the target, the {@link #end()} method is called to finish the movement.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
if(!moving) return;
|
||||||
|
progress += tpf * MOVE_SPEED;
|
||||||
|
if(progress > 1) progress = 1;
|
||||||
|
spatial.setLocalTranslation(quadInt(initPos,middlePos,endPos, easeInOut(progress)));
|
||||||
|
if(progress == 1) end();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends the movement by stopping the interpolation, running the action after the movement,
|
||||||
|
* and removing this control from the spatial.
|
||||||
|
*/
|
||||||
|
private void end(){
|
||||||
|
moving = false;
|
||||||
|
actionAfter.run();
|
||||||
|
spatial.removeControl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs quadratic interpolation between three points.
|
||||||
|
*
|
||||||
|
* @param p1 The initial point.
|
||||||
|
* @param p2 The middle point.
|
||||||
|
* @param p3 The final point.
|
||||||
|
* @param t The interpolation parameter (0 <= t <= 1).
|
||||||
|
* @return The interpolated point.
|
||||||
|
*/
|
||||||
|
private Vector3f quadInt(Vector3f p1, Vector3f p2, Vector3f p3, float t) {
|
||||||
|
// Quadratic interpolation: (1-t)^2 * p1 + 2 * (1-t) * t * p2 + t^2 * p3
|
||||||
|
float oneMinusT = 1 - t;
|
||||||
|
return p1.mult(oneMinusT * oneMinusT)
|
||||||
|
.add(p2.mult(2 * oneMinusT * t))
|
||||||
|
.add(p3.mult(t * t));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A smooth ease-in-out function for interpolation.
|
||||||
|
* It accelerates and decelerates the interpolation for a smoother effect.
|
||||||
|
*
|
||||||
|
* @param x The interpolation parameter (0 <= x <= 1).
|
||||||
|
* @return The adjusted interpolation value.
|
||||||
|
*/
|
||||||
|
private float easeInOut(float x){
|
||||||
|
return x < 0.5 ? 4 * x * x * x : (float) (1 - Math.pow(-2 * x + 2, 3) / 2);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,13 +1,23 @@
|
|||||||
package pp.mdga.client.gui;
|
package pp.mdga.client.animation;
|
||||||
|
|
||||||
import com.jme3.math.Quaternion;
|
import com.jme3.math.Quaternion;
|
||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.renderer.RenderManager;
|
import pp.mdga.client.InitControl;
|
||||||
import com.jme3.renderer.ViewPort;
|
|
||||||
import com.jme3.scene.control.AbstractControl;
|
|
||||||
import pp.mdga.game.BonusCard;
|
import pp.mdga.game.BonusCard;
|
||||||
|
|
||||||
public class SymbolControl extends AbstractControl {
|
/**
|
||||||
|
* A control that manages the animation of symbols representing different bonus card states.
|
||||||
|
* The symbol can animate with zoom, rotation, and translation effects based on the state of the bonus card.
|
||||||
|
*
|
||||||
|
* <p>The control supports three main states: SHIELD, SWAP, and TURBO. Each state has its own specific animation logic:
|
||||||
|
* <ul>
|
||||||
|
* <li>SHIELD: Zooms in and out, with a scaling effect.</li>
|
||||||
|
* <li>SWAP: Rotates the symbol 360 degrees.</li>
|
||||||
|
* <li>TURBO: Moves the symbol along the Y-axis with a zoom effect.</li>
|
||||||
|
* </ul>
|
||||||
|
* </p>
|
||||||
|
*/
|
||||||
|
public class SymbolControl extends InitControl {
|
||||||
private boolean zoomingIn = false;
|
private boolean zoomingIn = false;
|
||||||
private boolean zoomingOut = false;
|
private boolean zoomingOut = false;
|
||||||
private float zoomSpeed = 1f;
|
private float zoomSpeed = 1f;
|
||||||
@@ -18,7 +28,12 @@ public class SymbolControl extends AbstractControl {
|
|||||||
private Quaternion initialRotation = null;
|
private Quaternion initialRotation = null;
|
||||||
private float y = 5;
|
private float y = 5;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the symbol animation based on the current bonus card state.
|
||||||
|
* The method calls the corresponding update method for each state (SHIELD, SWAP, TURBO).
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void controlUpdate(float tpf) {
|
protected void controlUpdate(float tpf) {
|
||||||
if (state == null) return;
|
if (state == null) return;
|
||||||
@@ -30,11 +45,12 @@ protected void controlUpdate(float tpf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
/**
|
||||||
protected void controlRender(RenderManager rm, ViewPort vp) {
|
* Updates the symbol when the state is SHIELD. The symbol zooms in and then zooms out.
|
||||||
|
* When the zooming out finishes, the symbol is removed from the parent spatial.
|
||||||
}
|
*
|
||||||
|
* @param tpf Time per frame, the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
private void shieldUpdate(float tpf) {
|
private void shieldUpdate(float tpf) {
|
||||||
if (zoomingIn) {
|
if (zoomingIn) {
|
||||||
progress += tpf * zoomSpeed;
|
progress += tpf * zoomSpeed;
|
||||||
@@ -57,6 +73,12 @@ private void shieldUpdate(float tpf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the symbol when the state is SWAP. The symbol rotates 360 degrees.
|
||||||
|
* After the rotation finishes, the symbol is removed from the parent spatial.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
private void swapUpdate(float tpf) {
|
private void swapUpdate(float tpf) {
|
||||||
if (initialRotation == null) {
|
if (initialRotation == null) {
|
||||||
initialRotation = spatial.getLocalRotation().clone();
|
initialRotation = spatial.getLocalRotation().clone();
|
||||||
@@ -80,6 +102,12 @@ private void swapUpdate(float tpf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the symbol when the state is TURBO. The symbol moves along the Y-axis with a zoom effect.
|
||||||
|
* After the movement finishes, the symbol is removed from the parent spatial.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
private void turboUpdate(float tpf) {
|
private void turboUpdate(float tpf) {
|
||||||
if (zoomingIn) {
|
if (zoomingIn) {
|
||||||
progress += tpf * zoomSpeed;
|
progress += tpf * zoomSpeed;
|
||||||
@@ -103,6 +131,10 @@ private void turboUpdate(float tpf) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the SHIELD animation by zooming the symbol in and out.
|
||||||
|
* The symbol will first zoom in and then zoom out, and will be removed from the parent spatial once done.
|
||||||
|
*/
|
||||||
public void shield() {
|
public void shield() {
|
||||||
if (state != null) throw new RuntimeException("another state is avtive");
|
if (state != null) throw new RuntimeException("another state is avtive");
|
||||||
state = BonusCard.SHIELD;
|
state = BonusCard.SHIELD;
|
||||||
@@ -112,6 +144,10 @@ public void shield() {
|
|||||||
spatial.setLocalScale(1f);
|
spatial.setLocalScale(1f);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the SWAP animation by rotating the symbol 360 degrees.
|
||||||
|
* The symbol will rotate once and then be removed from the parent spatial.
|
||||||
|
*/
|
||||||
public void swap() {
|
public void swap() {
|
||||||
if (state != null) throw new RuntimeException("another state is avtive");
|
if (state != null) throw new RuntimeException("another state is avtive");
|
||||||
spatial.setLocalScale(3);
|
spatial.setLocalScale(3);
|
||||||
@@ -119,6 +155,10 @@ public void swap() {
|
|||||||
progress = -0.2f;
|
progress = -0.2f;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Starts the TURBO animation by moving the symbol along the Y-axis.
|
||||||
|
* The symbol will move upwards and then return to its initial position.
|
||||||
|
*/
|
||||||
public void turbo() {
|
public void turbo() {
|
||||||
if (state != null) throw new RuntimeException("another state is avtive");
|
if (state != null) throw new RuntimeException("another state is avtive");
|
||||||
spatial.setLocalScale(2);
|
spatial.setLocalScale(2);
|
||||||
@@ -128,19 +168,45 @@ public void turbo() {
|
|||||||
progress = 0;
|
progress = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs linear interpolation between two values.
|
||||||
|
*
|
||||||
|
* @param start The starting value.
|
||||||
|
* @param end The target value.
|
||||||
|
* @param t The interpolation parameter (0 <= t <= 1).
|
||||||
|
* @return The interpolated value.
|
||||||
|
*/
|
||||||
private static float lerp(float start, float end, float t) {
|
private static float lerp(float start, float end, float t) {
|
||||||
return (1 - t) * start + t * end;
|
return (1 - t) * start + t * end;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ease-out function for smoothing the interpolation.
|
||||||
|
*
|
||||||
|
* @param t The interpolation parameter (0 <= t <= 1).
|
||||||
|
* @return The eased value.
|
||||||
|
*/
|
||||||
private static float easeOut(float t) {
|
private static float easeOut(float t) {
|
||||||
return (float) Math.sqrt(1 - Math.pow(t - 1, 2));
|
return (float) Math.sqrt(1 - Math.pow(t - 1, 2));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ease-in-out function for smoothing the interpolation.
|
||||||
|
*
|
||||||
|
* @param t The interpolation parameter (0 <= t <= 1).
|
||||||
|
* @return The eased value.
|
||||||
|
*/
|
||||||
private float easeInOut(float t) {
|
private float easeInOut(float t) {
|
||||||
if (t > 1) t = 1;
|
if (t > 1) t = 1;
|
||||||
return (float) -(Math.cos(Math.PI * t) - 1) / 2;
|
return (float) -(Math.cos(Math.PI * t) - 1) / 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ease-in function for smoothing the interpolation.
|
||||||
|
*
|
||||||
|
* @param t The interpolation parameter (0 <= t <= 1).
|
||||||
|
* @return The eased value.
|
||||||
|
*/
|
||||||
private float easeIn(float t) {
|
private float easeIn(float t) {
|
||||||
return t * t * t * t;
|
return t * t * t * t;
|
||||||
}
|
}
|
||||||
@@ -0,0 +1,110 @@
|
|||||||
|
package pp.mdga.client.animation;
|
||||||
|
|
||||||
|
import pp.mdga.client.InitControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A control that applies a zoom effect to a spatial, smoothly scaling it in and out.
|
||||||
|
* The zoom effect can be customized with speed and scaling factor.
|
||||||
|
*
|
||||||
|
* <p>The control supports zooming in and out with ease-in and ease-out transitions.
|
||||||
|
* It starts by zooming in, and once complete, it zooms out, eventually removing the spatial from its parent when the animation ends.</p>
|
||||||
|
*/
|
||||||
|
public class ZoomControl extends InitControl {
|
||||||
|
private boolean zoomingIn = false;
|
||||||
|
private boolean zoomingOut = false;
|
||||||
|
private float progress = 0;
|
||||||
|
private float zoomSpeed = 1f;
|
||||||
|
private float zoomFactor = 1f;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ZoomControl with the default zoom speed.
|
||||||
|
*/
|
||||||
|
public ZoomControl() {
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new ZoomControl with a specified zoom speed.
|
||||||
|
*
|
||||||
|
* @param speed The speed at which the zoom effect occurs.
|
||||||
|
*/
|
||||||
|
public ZoomControl(float speed) {
|
||||||
|
zoomSpeed = speed;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the spatial for the zoom effect. This method is called when the control is added to the spatial.
|
||||||
|
* It sets the zooming state to zooming in.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void initSpatial() {
|
||||||
|
zoomingIn = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the zoom effect over time, either zooming in or zooming out.
|
||||||
|
*
|
||||||
|
* @param tpf Time per frame, the time elapsed since the last frame.
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
protected void controlUpdate(float tpf) {
|
||||||
|
if (zoomingIn) {
|
||||||
|
progress += tpf * zoomSpeed;
|
||||||
|
if (progress > 1) progress = 1;
|
||||||
|
spatial.setLocalScale(lerp(0, zoomFactor, easeOut(progress)));
|
||||||
|
if (progress >= 1) {
|
||||||
|
zoomingIn = false;
|
||||||
|
zoomingOut = true;
|
||||||
|
progress = 0;
|
||||||
|
}
|
||||||
|
} else if (zoomingOut) {
|
||||||
|
progress += tpf * zoomSpeed;
|
||||||
|
spatial.setLocalScale(lerp(zoomFactor, 0, easeIn(progress)));
|
||||||
|
if (progress > 1) {
|
||||||
|
zoomingOut = false;
|
||||||
|
end();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ends the zoom animation by removing the spatial from its parent and the control from the spatial.
|
||||||
|
*/
|
||||||
|
private void end() {
|
||||||
|
spatial.removeFromParent();
|
||||||
|
spatial.removeControl(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Performs linear interpolation between two values.
|
||||||
|
*
|
||||||
|
* @param start The starting value.
|
||||||
|
* @param end The target value.
|
||||||
|
* @param t The interpolation parameter (0 <= t <= 1).
|
||||||
|
* @return The interpolated value.
|
||||||
|
*/
|
||||||
|
private static float lerp(float start, float end, float t) {
|
||||||
|
return (1 - t) * start + t * end;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ease-out function for smoothing the zoom-in transition.
|
||||||
|
*
|
||||||
|
* @param x The interpolation parameter (0 <= x <= 1).
|
||||||
|
* @return The eased value.
|
||||||
|
*/
|
||||||
|
private float easeOut(float x) {
|
||||||
|
return x == 1 ? 1 : (float) (1 - Math.pow(2, -10 * x));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Ease-in function for smoothing the zoom-out transition.
|
||||||
|
*
|
||||||
|
* @param x The interpolation parameter (0 <= x <= 1).
|
||||||
|
* @return The eased value.
|
||||||
|
*/
|
||||||
|
private float easeIn(float x) {
|
||||||
|
return x == 0 ? 0 : (float) Math.pow(2, 10 * x - 10);
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -2,4 +2,7 @@
|
|||||||
|
|
||||||
import pp.mdga.client.Asset;
|
import pp.mdga.client.Asset;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Record for holding Asset information
|
||||||
|
*/
|
||||||
record AssetOnMap(Asset asset, int x, int y, float rot) {}
|
record AssetOnMap(Asset asset, int x, int y, float rot) {}
|
||||||
|
|||||||
@@ -9,34 +9,45 @@
|
|||||||
import com.jme3.scene.control.AbstractControl;
|
import com.jme3.scene.control.AbstractControl;
|
||||||
import pp.mdga.client.Asset;
|
import pp.mdga.client.Asset;
|
||||||
import pp.mdga.client.MdgaApp;
|
import pp.mdga.client.MdgaApp;
|
||||||
|
import pp.mdga.client.animation.MoveControl;
|
||||||
import pp.mdga.client.gui.DiceControl;
|
import pp.mdga.client.gui.DiceControl;
|
||||||
import pp.mdga.game.Color;
|
import pp.mdga.game.Color;
|
||||||
|
import pp.mdga.game.Piece;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* BoardHandler is responsible for managing the game board in the MDGA client, including handling
|
||||||
|
* the initialization, movement, and management of game pieces and assets.
|
||||||
|
* It works closely with the MdgaApp to create and manipulate 3D models of assets, track player pieces,
|
||||||
|
* and manage movement across the game board.
|
||||||
|
*/
|
||||||
public class BoardHandler {
|
public class BoardHandler {
|
||||||
|
// Constants defining the grid size and elevation of the board
|
||||||
private static final float GRID_SIZE = 1.72f;
|
private static final float GRID_SIZE = 1.72f;
|
||||||
private static final float GRID_ELEVATION = 0.0f;
|
private static final float GRID_ELEVATION = 0.0f;
|
||||||
private static final String MAP_NAME = "Maps/map.mdga";
|
private static final String MAP_NAME = "Maps/map.mdga";
|
||||||
|
|
||||||
|
// The main application instance for accessing game assets and logic
|
||||||
private final MdgaApp app;
|
private final MdgaApp app;
|
||||||
|
|
||||||
|
// Collection of in-game assets and board elements
|
||||||
private ArrayList<NodeControl> infield;
|
private ArrayList<NodeControl> infield;
|
||||||
private Map<UUID, PieceControl> pieces;
|
private Map<UUID, PieceControl> pieces;
|
||||||
|
|
||||||
private Map<Color, List<AssetOnMap>> colorAssetsMap;
|
private Map<Color, List<AssetOnMap>> colorAssetsMap;
|
||||||
private Map<Color, List<NodeControl>> homeNodesMap;
|
private Map<Color, List<NodeControl>> homeNodesMap;
|
||||||
private Map<Color, List<NodeControl>> waitingNodesMap;
|
private Map<Color, List<NodeControl>> waitingNodesMap;
|
||||||
private Map<Color, List<PieceControl>> waitingPiecesMap;
|
private Map<Color, List<PieceControl>> waitingPiecesMap;
|
||||||
|
private Map<Color, Map<UUID, NodeControl>> waitingNodes;
|
||||||
private Map<UUID, Color> pieceColor;
|
private Map<UUID, Color> pieceColor;
|
||||||
|
|
||||||
private Node rootNodeBoard;
|
private final Node rootNodeBoard;
|
||||||
private final Node rootNode;
|
private final Node rootNode;
|
||||||
|
|
||||||
private final FilterPostProcessor fpp;
|
private final FilterPostProcessor fpp;
|
||||||
|
|
||||||
private boolean isInitialised;
|
private boolean isInitialised;
|
||||||
|
|
||||||
|
// Flags and lists for handling piece selection and movement
|
||||||
private List<PieceControl> selectableOwnPieces;
|
private List<PieceControl> selectableOwnPieces;
|
||||||
private List<PieceControl> selectableEnemyPieces;
|
private List<PieceControl> selectableEnemyPieces;
|
||||||
private List<NodeControl> outlineNodes;
|
private List<NodeControl> outlineNodes;
|
||||||
@@ -44,6 +55,14 @@ public class BoardHandler {
|
|||||||
private PieceControl selectedEnemyPiece;
|
private PieceControl selectedEnemyPiece;
|
||||||
private DiceControl diceControl;
|
private DiceControl diceControl;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a new BoardHandler.
|
||||||
|
*
|
||||||
|
* @param app The main application instance
|
||||||
|
* @param rootNode The root node where the board will be attached
|
||||||
|
* @param fpp The post-processor for effects like shadows or filters
|
||||||
|
* @throws RuntimeException if the app is null
|
||||||
|
*/
|
||||||
public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) {
|
public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) {
|
||||||
if(app == null) throw new RuntimeException("app is null");
|
if(app == null) throw new RuntimeException("app is null");
|
||||||
|
|
||||||
@@ -54,6 +73,9 @@ public BoardHandler(MdgaApp app, Node rootNode, FilterPostProcessor fpp) {
|
|||||||
isInitialised = false;
|
isInitialised = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the game board by setting up the pieces and nodes.
|
||||||
|
*/
|
||||||
public void init() {
|
public void init() {
|
||||||
isInitialised = true;
|
isInitialised = true;
|
||||||
selectableOwnPieces = new ArrayList<>();
|
selectableOwnPieces = new ArrayList<>();
|
||||||
@@ -65,17 +87,30 @@ public void init() {
|
|||||||
rootNode.attachChild(rootNodeBoard);
|
rootNode.attachChild(rootNodeBoard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuts down the board handler by detaching all board-related nodes and clearing selected pieces.
|
||||||
|
*/
|
||||||
public void shutdown(){
|
public void shutdown(){
|
||||||
clearSelectable();
|
clearSelectable();
|
||||||
isInitialised = false;
|
isInitialised = false;
|
||||||
rootNode.detachChild(rootNodeBoard);
|
rootNode.detachChild(rootNodeBoard);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Adds an asset to the map of player assets, ensuring that the player does not have too many assets.
|
||||||
|
*
|
||||||
|
* @param col The color of the player
|
||||||
|
* @param assetOnMap The asset to be added
|
||||||
|
* @throws RuntimeException if there are too many assets for the player
|
||||||
|
*/
|
||||||
private void addFigureToPlayerMap(Color col, AssetOnMap assetOnMap) {
|
private void addFigureToPlayerMap(Color col, AssetOnMap assetOnMap) {
|
||||||
List<AssetOnMap> inMap = addItemToMapList(colorAssetsMap, col, assetOnMap);
|
List<AssetOnMap> inMap = addItemToMapList(colorAssetsMap, col, assetOnMap);
|
||||||
if (inMap.size() > 4) throw new RuntimeException("to many assets for " + col);
|
if (inMap.size() > 4) throw new RuntimeException("to many assets for " + col);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the map with the assets loaded from the map file and corresponding nodes.
|
||||||
|
*/
|
||||||
private void initMap() {
|
private void initMap() {
|
||||||
pieces = new HashMap<>();
|
pieces = new HashMap<>();
|
||||||
colorAssetsMap = new HashMap<>();
|
colorAssetsMap = new HashMap<>();
|
||||||
@@ -86,6 +121,12 @@ private void initMap() {
|
|||||||
pieceColor = new HashMap<>();
|
pieceColor = new HashMap<>();
|
||||||
diceControl = new DiceControl(app.getAssetManager());
|
diceControl = new DiceControl(app.getAssetManager());
|
||||||
diceControl.create(new Vector3f(0,0,0), 0.7f, true);
|
diceControl.create(new Vector3f(0,0,0), 0.7f, true);
|
||||||
|
waitingNodes = new HashMap<>();
|
||||||
|
waitingNodes.put(Color.AIRFORCE, new HashMap<>());
|
||||||
|
waitingNodes.put(Color.ARMY, new HashMap<>());
|
||||||
|
waitingNodes.put(Color.NAVY, new HashMap<>());
|
||||||
|
waitingNodes.put(Color.CYBER, new HashMap<>());
|
||||||
|
|
||||||
|
|
||||||
List<AssetOnMap> assetOnMaps = MapLoader.loadMap(MAP_NAME);
|
List<AssetOnMap> assetOnMaps = MapLoader.loadMap(MAP_NAME);
|
||||||
|
|
||||||
@@ -111,6 +152,13 @@ private void initMap() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts an asset to its corresponding color.
|
||||||
|
*
|
||||||
|
* @param asset The asset to be converted
|
||||||
|
* @return The color associated with the asset
|
||||||
|
* @throws RuntimeException if the asset is invalid
|
||||||
|
*/
|
||||||
private Color assetToColor(Asset asset) {
|
private Color assetToColor(Asset asset) {
|
||||||
return switch (asset) {
|
return switch (asset) {
|
||||||
case lw -> Color.AIRFORCE;
|
case lw -> Color.AIRFORCE;
|
||||||
@@ -121,6 +169,14 @@ private Color assetToColor(Asset asset) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Creates a 3D model of an asset and adds it to the board.
|
||||||
|
*
|
||||||
|
* @param asset The asset to be displayed
|
||||||
|
* @param pos The position of the asset on the board
|
||||||
|
* @param rot The rotation of the asset
|
||||||
|
* @return The Spatial representation of the asset
|
||||||
|
*/
|
||||||
private Spatial createModel(Asset asset, Vector3f pos, float rot) {
|
private Spatial createModel(Asset asset, Vector3f pos, float rot) {
|
||||||
String modelName = asset.getModelPath();
|
String modelName = asset.getModelPath();
|
||||||
String texName = asset.getDiffPath();
|
String texName = asset.getDiffPath();
|
||||||
@@ -137,10 +193,23 @@ private Spatial createModel(Asset asset, Vector3f pos, float rot) {
|
|||||||
return model;
|
return model;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Converts grid coordinates to world space.
|
||||||
|
*
|
||||||
|
* @param x The x-coordinate on the grid
|
||||||
|
* @param y The y-coordinate on the grid
|
||||||
|
* @return The corresponding world position
|
||||||
|
*/
|
||||||
private static Vector3f gridToWorld(int x, int y) {
|
private static Vector3f gridToWorld(int x, int y) {
|
||||||
return new Vector3f(GRID_SIZE * x, GRID_SIZE * y, GRID_ELEVATION);
|
return new Vector3f(GRID_SIZE * x, GRID_SIZE * y, GRID_ELEVATION);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Displays an asset on the map at the given position with the specified rotation.
|
||||||
|
*
|
||||||
|
* @param assetOnMap The asset to be displayed.
|
||||||
|
* @return A spatial representation of the asset at the specified location and rotation.
|
||||||
|
*/
|
||||||
private Spatial displayAsset(AssetOnMap assetOnMap) {
|
private Spatial displayAsset(AssetOnMap assetOnMap) {
|
||||||
int x = assetOnMap.x();
|
int x = assetOnMap.x();
|
||||||
int y = assetOnMap.y();
|
int y = assetOnMap.y();
|
||||||
@@ -162,6 +231,13 @@ private void addHomeNode(Map<Color, List<NodeControl>> map, Color color, AssetOn
|
|||||||
if (homeNodes.size() > 4) throw new RuntimeException("too many homeNodes for " + color);
|
if (homeNodes.size() > 4) throw new RuntimeException("too many homeNodes for " + color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Calculates the rotation angle required to move a piece from one position to another.
|
||||||
|
*
|
||||||
|
* @param prev The previous position.
|
||||||
|
* @param next The target position.
|
||||||
|
* @return The rotation angle in degrees.
|
||||||
|
*/
|
||||||
private float getRotationMove(Vector3f prev, Vector3f next) {
|
private float getRotationMove(Vector3f prev, Vector3f next) {
|
||||||
Vector3f direction = next.subtract(prev).normalizeLocal();
|
Vector3f direction = next.subtract(prev).normalizeLocal();
|
||||||
//I had to reverse dir.y, because then it worked.
|
//I had to reverse dir.y, because then it worked.
|
||||||
@@ -170,6 +246,14 @@ private float getRotationMove(Vector3f prev, Vector3f next) {
|
|||||||
return newRot;
|
return newRot;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Recursively moves a piece from its current index to the destination index,
|
||||||
|
* to keep track of the piece rotation.
|
||||||
|
*
|
||||||
|
* @param uuid The UUID of the piece to move.
|
||||||
|
* @param curIndex The current index of the piece.
|
||||||
|
* @param moveIndex The target index to move the piece to.
|
||||||
|
*/
|
||||||
private void movePieceRek(UUID uuid, int curIndex, int moveIndex){
|
private void movePieceRek(UUID uuid, int curIndex, int moveIndex){
|
||||||
if (curIndex == moveIndex) return;
|
if (curIndex == moveIndex) return;
|
||||||
|
|
||||||
@@ -202,6 +286,12 @@ private Vector3f getWaitingPos(Color color){
|
|||||||
return getMeanPosition(waitingNodesMap.get(color).stream().map(NodeControl::getLocation).toList());
|
return getMeanPosition(waitingNodesMap.get(color).stream().map(NodeControl::getLocation).toList());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the mean position of a list of vectors.
|
||||||
|
*
|
||||||
|
* @param vectors The list of vectors.
|
||||||
|
* @return The mean position as a Vector3f.
|
||||||
|
*/
|
||||||
public static Vector3f getMeanPosition(List<Vector3f> vectors) {
|
public static Vector3f getMeanPosition(List<Vector3f> vectors) {
|
||||||
if (vectors.isEmpty()) return new Vector3f(0, 0, 0);
|
if (vectors.isEmpty()) return new Vector3f(0, 0, 0);
|
||||||
|
|
||||||
@@ -212,9 +302,14 @@ public static Vector3f getMeanPosition(List<Vector3f> vectors) {
|
|||||||
return sum.divide(vectors.size());
|
return sum.divide(vectors.size());
|
||||||
}
|
}
|
||||||
|
|
||||||
//public methods****************************************************************************************************
|
/**
|
||||||
|
* Adds a player to the game by associating a color and a list of UUIDs to corresponding assets and waiting nodes.
|
||||||
|
*
|
||||||
|
* @param color the color of the player
|
||||||
|
* @param uuid the list of UUIDs representing the player's assets
|
||||||
|
* @throws RuntimeException if the number of assets or waiting nodes does not match the provided UUIDs
|
||||||
|
*/
|
||||||
public void addPlayer(Color color, List<UUID> uuid) {
|
public void addPlayer(Color color, List<UUID> uuid) {
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
|
||||||
|
|
||||||
List<AssetOnMap> playerAssets = colorAssetsMap.get(color);
|
List<AssetOnMap> playerAssets = colorAssetsMap.get(color);
|
||||||
if (playerAssets == null) throw new RuntimeException("Assets for Player color are not defined");
|
if (playerAssets == null) throw new RuntimeException("Assets for Player color are not defined");
|
||||||
@@ -226,20 +321,34 @@ public void addPlayer(Color color, List<UUID> uuid) {
|
|||||||
|
|
||||||
for (int i = 0; i < playerAssets.size(); i++){
|
for (int i = 0; i < playerAssets.size(); i++){
|
||||||
AssetOnMap assetOnMap = playerAssets.get(i);
|
AssetOnMap assetOnMap = playerAssets.get(i);
|
||||||
|
UUID pieceUuid = uuid.get(i);
|
||||||
|
|
||||||
|
// Initialize PieceControl
|
||||||
PieceControl pieceControl = displayAndControl(assetOnMap, new PieceControl(assetOnMap.rot(), app.getAssetManager(), app, fpp));
|
PieceControl pieceControl = displayAndControl(assetOnMap, new PieceControl(assetOnMap.rot(), app.getAssetManager(), app, fpp));
|
||||||
pieceControl.setRotation(assetOnMap.rot());
|
pieceControl.setRotation(assetOnMap.rot());
|
||||||
movePieceToNode(pieceControl, waitNodes.get(i));
|
|
||||||
|
|
||||||
pieces.put(uuid.get(i), pieceControl);
|
// Assign piece to waiting node
|
||||||
|
NodeControl waitNode = getNextWaitingNode(color);
|
||||||
|
waitingNodes.get(color).put(pieceUuid, waitNode);
|
||||||
|
|
||||||
pieceColor.put(uuid.get(i), color);
|
// Move piece to node
|
||||||
|
movePieceToNode(pieceControl, waitNode);
|
||||||
|
|
||||||
|
// Update mappings
|
||||||
|
pieces.put(pieceUuid, pieceControl);
|
||||||
|
pieceColor.put(pieceUuid, color);
|
||||||
addItemToMapList(waitingPiecesMap, color, pieceControl);
|
addItemToMapList(waitingPiecesMap, color, pieceControl);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void moveHomePiece(UUID uuid, int index){
|
/**
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
* Moves a piece to its corresponding home node based on the given index.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to move
|
||||||
|
* @param index the index of the home node to move the piece to
|
||||||
|
* @throws RuntimeException if the UUID is not mapped to a color or if the home nodes are not properly defined
|
||||||
|
*/
|
||||||
|
private void moveHomePiece(UUID uuid, int index){
|
||||||
|
|
||||||
Color color = pieceColor.get(uuid);
|
Color color = pieceColor.get(uuid);
|
||||||
if(color == null) throw new RuntimeException("uuid is not mapped to a color");
|
if(color == null) throw new RuntimeException("uuid is not mapped to a color");
|
||||||
@@ -257,90 +366,145 @@ public void moveHomePiece(UUID uuid, int index){
|
|||||||
NodeControl lastHomeNode = homeNodes.get(homeNodes.size()-1);
|
NodeControl lastHomeNode = homeNodes.get(homeNodes.size()-1);
|
||||||
|
|
||||||
pieceControl.setRotation(getRotationMove(firstHomeNode.getLocation(), lastHomeNode.getLocation()));
|
pieceControl.setRotation(getRotationMove(firstHomeNode.getLocation(), lastHomeNode.getLocation()));
|
||||||
|
app.getModelSynchronize().animationEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void movePieceStart(UUID uuid, int nodeIndex){
|
/**
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
* Starts the movement of a piece to a target node based on the given index.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to move
|
||||||
|
* @param nodeIndex the index of the target node to move the piece to
|
||||||
|
* @throws RuntimeException if the UUID is not mapped to a color or the piece control is not found
|
||||||
|
* @throws IllegalArgumentException if the node index is invalid
|
||||||
|
*/
|
||||||
|
private void movePieceStart(UUID uuid, int nodeIndex){
|
||||||
|
|
||||||
|
// Farbe des Pieces abrufen
|
||||||
Color color = pieceColor.get(uuid);
|
Color color = pieceColor.get(uuid);
|
||||||
if(color == null) throw new RuntimeException("uuid is not mapped to a color");
|
if (color == null) throw new RuntimeException("UUID is not mapped to a color");
|
||||||
|
|
||||||
|
// PieceControl abrufen
|
||||||
PieceControl pieceControl = pieces.get(uuid);
|
PieceControl pieceControl = pieces.get(uuid);
|
||||||
movePieceToNode(pieceControl, infield.get(nodeIndex));
|
if (pieceControl == null) throw new RuntimeException("PieceControl not found for UUID: " + uuid);
|
||||||
|
|
||||||
|
// Zielknoten abrufen und prüfen
|
||||||
|
if (nodeIndex < 0 || nodeIndex >= infield.size()) {
|
||||||
|
throw new IllegalArgumentException("Invalid nodeIndex: " + nodeIndex);
|
||||||
|
}
|
||||||
|
NodeControl targetNode = infield.get(nodeIndex);
|
||||||
|
|
||||||
|
movePieceToNode(pieceControl, targetNode);
|
||||||
|
|
||||||
removeItemFromMapList(waitingPiecesMap, color, pieceControl);
|
removeItemFromMapList(waitingPiecesMap, color, pieceControl);
|
||||||
|
waitingNodes.get(color).remove(uuid);
|
||||||
|
app.getModelSynchronize().animationEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void movePiece(UUID uuid, int curIndex, int moveIndex){
|
/**
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
* Moves a piece from its current position to the target position based on the given indexes.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to move
|
||||||
|
* @param curIndex the current index of the piece
|
||||||
|
* @param moveIndex the target index of the move
|
||||||
|
*/
|
||||||
|
private void movePiece(UUID uuid, int curIndex, int moveIndex){
|
||||||
|
|
||||||
movePieceRek(uuid, curIndex, moveIndex);
|
movePieceRek(uuid, curIndex, moveIndex);
|
||||||
|
app.getModelSynchronize().animationEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void throwPiece(UUID uuid){
|
/**
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
* Throws a piece to the next available waiting node and updates the waiting node mapping.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to throw
|
||||||
|
* @throws RuntimeException if the UUID is not mapped to a color or if no available waiting nodes are found
|
||||||
|
*/
|
||||||
|
private void throwPiece(UUID uuid){
|
||||||
|
|
||||||
|
// Farbe des Pieces abrufen
|
||||||
Color color = pieceColor.get(uuid);
|
Color color = pieceColor.get(uuid);
|
||||||
if(color == null) throw new RuntimeException("uuid is not mapped to a color");
|
if (color == null) throw new RuntimeException("UUID is not mapped to a color");
|
||||||
|
|
||||||
|
|
||||||
|
// PieceControl abrufen
|
||||||
PieceControl pieceControl = pieces.get(uuid);
|
PieceControl pieceControl = pieces.get(uuid);
|
||||||
List<NodeControl> waitNodes = waitingNodesMap.get(color);
|
if (pieceControl == null) throw new RuntimeException("PieceControl not found for UUID: " + uuid);
|
||||||
List<PieceControl> waitPieces = waitingPiecesMap.get(color);
|
|
||||||
|
|
||||||
movePieceToNode(pieceControl, waitNodes.get(waitPieces.size()));
|
// Nächste freie Waiting Node abrufen
|
||||||
|
NodeControl nextWaitNode = getNextWaitingNode(color);
|
||||||
|
if (nextWaitNode == null) {
|
||||||
|
throw new IllegalStateException("No available waiting nodes for color: " + color);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Bewegung durchführen
|
||||||
|
movePieceToNode(pieceControl, nextWaitNode);
|
||||||
|
|
||||||
|
// Waiting Nodes aktualisieren
|
||||||
|
waitingNodes.get(color).put(uuid, nextWaitNode);
|
||||||
|
|
||||||
|
// Synchronisation oder Animation
|
||||||
pieceControl.rotateInit();
|
pieceControl.rotateInit();
|
||||||
|
app.getModelSynchronize().animationEnd();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates the shield for the specified piece.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to shield
|
||||||
|
*/
|
||||||
public void shieldPiece(UUID uuid){
|
public void shieldPiece(UUID uuid){
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
|
||||||
|
|
||||||
pieces.get(uuid).activateShield();
|
pieces.get(uuid).activateShield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivates the shield for the specified piece.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to unshield
|
||||||
|
*/
|
||||||
public void unshieldPiece(UUID uuid){
|
public void unshieldPiece(UUID uuid){
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
|
||||||
|
|
||||||
pieces.get(uuid).deactivateShield();
|
pieces.get(uuid).deactivateShield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppresses the shield for the specified piece.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to suppress the shield
|
||||||
|
*/
|
||||||
public void suppressShield(UUID uuid){
|
public void suppressShield(UUID uuid){
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
|
||||||
|
|
||||||
pieces.get(uuid).suppressShield();
|
pieces.get(uuid).suppressShield();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void swapPieces(UUID piece1, UUID piece2){
|
/**
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
* Swaps the positions and rotations of two pieces.
|
||||||
|
*
|
||||||
|
* @param p1 the first piece to swap
|
||||||
|
* @param p2 the second piece to swap
|
||||||
|
* @param loc1 the original location of the first piece
|
||||||
|
* @param rot1 the original rotation of the first piece
|
||||||
|
* @param loc2 the original location of the second piece
|
||||||
|
* @param rot2 the original rotation of the second piece
|
||||||
|
*/
|
||||||
|
private void swapPieces(PieceControl p1, PieceControl p2, Vector3f loc1, float rot1, Vector3f loc2, float rot2){
|
||||||
|
p1.setLocation(loc2);
|
||||||
|
p2.setLocation(loc1);
|
||||||
|
|
||||||
PieceControl piece1Control = pieces.get(piece1);
|
p1.setRotation(rot2);
|
||||||
PieceControl piece2Control = pieces.get(piece2);
|
p2.setRotation(rot1);
|
||||||
|
|
||||||
if(piece1Control == null) throw new RuntimeException("piece1 UUID is not valid");
|
app.getModelSynchronize().animationEnd();
|
||||||
if(piece2Control == null) throw new RuntimeException("piece2 UUID is not valid");
|
|
||||||
|
|
||||||
float rot1 = piece1Control.getRotation();
|
|
||||||
float rot2 = piece2Control.getRotation();
|
|
||||||
|
|
||||||
piece1Control.setRotation(rot2);
|
|
||||||
piece2Control.setRotation(rot1);
|
|
||||||
|
|
||||||
Vector3f pos1 = piece1Control.getLocation().clone();
|
|
||||||
Vector3f pos2 = piece2Control.getLocation().clone();
|
|
||||||
|
|
||||||
piece1Control.setLocation(pos2);
|
|
||||||
piece2Control.setLocation(pos1);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void highlight(UUID uuid, boolean bool){
|
/**
|
||||||
if (!isInitialised) throw new RuntimeException("BoardHandler is not initialized");
|
* Outlines the possible move nodes for a list of pieces based on the move indices and whether it's a home move.
|
||||||
|
*
|
||||||
pieces.get(uuid).highlight(bool);
|
* @param pieces the list of UUIDs representing the pieces to outline
|
||||||
pieces.get(uuid).setSelectable(bool);
|
* @param moveIndexe the list of indices for the target move nodes
|
||||||
|
* @param homeMoves the list indicating whether the move is a home move
|
||||||
}
|
* @throws RuntimeException if the sizes of the input lists do not match
|
||||||
|
*/
|
||||||
//called when (dice) moveNum is received from server to display the movable pieces and corresponding moveNodes
|
|
||||||
public void outlineMove(List<UUID> pieces, List<Integer> moveIndexe, List<Boolean> homeMoves) {
|
public void outlineMove(List<UUID> pieces, List<Integer> moveIndexe, List<Boolean> homeMoves) {
|
||||||
if(pieces.size() != moveIndexe.size() || pieces.size() != homeMoves.size()) throw new RuntimeException("arrays are not the same size");
|
if(pieces.size() != moveIndexe.size() || pieces.size() != homeMoves.size()) throw new RuntimeException("arrays are not the same size");
|
||||||
|
|
||||||
@@ -370,7 +534,12 @@ public void outlineMove(List<UUID> pieces, List<Integer> moveIndexe, List<Boolea
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//called when swap notification is received to highlight and select own/enemy pieces
|
/**
|
||||||
|
* Outlines the pieces that can be swapped based on the provided own and enemy pieces.
|
||||||
|
*
|
||||||
|
* @param ownPieces the list of UUIDs representing the player's pieces
|
||||||
|
* @param enemyPieces the list of UUIDs representing the enemy's pieces
|
||||||
|
*/
|
||||||
public void outlineSwap(List<UUID> ownPieces, List<UUID> enemyPieces){
|
public void outlineSwap(List<UUID> ownPieces, List<UUID> enemyPieces){
|
||||||
|
|
||||||
selectableEnemyPieces.clear();
|
selectableEnemyPieces.clear();
|
||||||
@@ -394,6 +563,11 @@ public void outlineSwap(List<UUID> ownPieces, List<UUID> enemyPieces){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Outlines the pieces that can be shielded based on the provided list of pieces.
|
||||||
|
*
|
||||||
|
* @param pieces the list of UUIDs representing the pieces to be shielded
|
||||||
|
*/
|
||||||
public void outlineShield(List<UUID> pieces){
|
public void outlineShield(List<UUID> pieces){
|
||||||
selectableOwnPieces.clear();
|
selectableOwnPieces.clear();
|
||||||
selectableEnemyPieces.clear();
|
selectableEnemyPieces.clear();
|
||||||
@@ -409,7 +583,11 @@ public void outlineShield(List<UUID> pieces){
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
//called from inputSynchronizer when a piece is selectable
|
/**
|
||||||
|
* Selects a piece from either the own or enemy pieces based on the input and deselects others if needed.
|
||||||
|
*
|
||||||
|
* @param pieceSelected the PieceControl instance representing the piece selected by the user
|
||||||
|
*/
|
||||||
public void pieceSelect(PieceControl pieceSelected) {
|
public void pieceSelect(PieceControl pieceSelected) {
|
||||||
boolean isSelected = pieceSelected.isSelected();
|
boolean isSelected = pieceSelected.isSelected();
|
||||||
if(selectableOwnPieces.contains(pieceSelected)){
|
if(selectableOwnPieces.contains(pieceSelected)){
|
||||||
@@ -443,7 +621,9 @@ else if(selectableEnemyPieces.contains(pieceSelected)) {
|
|||||||
app.getModelSynchronize().select(getKeyByValue(pieces, selectedOwnPiece), getKeyByValue(pieces, selectedEnemyPiece));
|
app.getModelSynchronize().select(getKeyByValue(pieces, selectedOwnPiece), getKeyByValue(pieces, selectedEnemyPiece));
|
||||||
}
|
}
|
||||||
|
|
||||||
//called when view is no longer needed to select pieces
|
/**
|
||||||
|
* Clears all highlighted, selectable, and selected pieces and nodes.
|
||||||
|
*/
|
||||||
public void clearSelectable(){
|
public void clearSelectable(){
|
||||||
for(PieceControl p : selectableEnemyPieces) {
|
for(PieceControl p : selectableEnemyPieces) {
|
||||||
p.unSelect();
|
p.unSelect();
|
||||||
@@ -465,16 +645,20 @@ public void clearSelectable(){
|
|||||||
selectedOwnPiece = null;
|
selectedOwnPiece = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void enableHover(UUID uuid){
|
/**
|
||||||
pieces.get(uuid).setHoverable(true);
|
* Displays the dice for the specified color at the appropriate position.
|
||||||
}
|
*
|
||||||
|
* @param color the color of the player whose dice should be displayed
|
||||||
|
*/
|
||||||
public void showDice(Color color){
|
public void showDice(Color color){
|
||||||
rootNodeBoard.attachChild(diceControl.getSpatial());
|
rootNodeBoard.attachChild(diceControl.getSpatial());
|
||||||
diceControl.setPos(getWaitingPos(color).add(new Vector3f(0,0,4)));
|
diceControl.setPos(getWaitingPos(color).add(new Vector3f(0,0,4)));
|
||||||
diceControl.spin();
|
diceControl.spin();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Hides the dice from the view.
|
||||||
|
*/
|
||||||
public void hideDice(){
|
public void hideDice(){
|
||||||
diceControl.hide();
|
diceControl.hide();
|
||||||
}
|
}
|
||||||
@@ -488,4 +672,107 @@ private <K, V> K getKeyByValue(Map<K, V> map, V value) {
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates the movement of a piece from its current index to a target index.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to animate
|
||||||
|
* @param curIndex the current index of the piece
|
||||||
|
* @param moveIndex the target index to animate the piece to
|
||||||
|
*/
|
||||||
|
public void movePieceAnim(UUID uuid, int curIndex, int moveIndex){
|
||||||
|
pieces.get(uuid).getSpatial().addControl(new MoveControl(
|
||||||
|
infield.get(curIndex).getLocation(),
|
||||||
|
infield.get(moveIndex).getLocation(),
|
||||||
|
()->movePiece(uuid,curIndex,moveIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates the movement of a piece to its home position based on the given home index.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to animate
|
||||||
|
* @param homeIndex the index of the home node to move the piece to
|
||||||
|
*/
|
||||||
|
public void movePieceHomeAnim(UUID uuid, int homeIndex){
|
||||||
|
pieces.get(uuid).getSpatial().addControl(new MoveControl(
|
||||||
|
pieces.get(uuid).getLocation(),
|
||||||
|
homeNodesMap.get(pieceColor.get(uuid)).get(homeIndex).getLocation(),
|
||||||
|
()->moveHomePiece(uuid,homeIndex)));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates the start of the movement of a piece to a target index.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to animate
|
||||||
|
* @param moveIndex the target index to animate the piece to
|
||||||
|
*/
|
||||||
|
public void movePieceStartAnim(UUID uuid, int moveIndex){
|
||||||
|
pieces.get(uuid).getSpatial().addControl(new MoveControl(
|
||||||
|
pieces.get(uuid).getLocation(),
|
||||||
|
infield.get(moveIndex).getLocation(),
|
||||||
|
()->movePieceStart(uuid, moveIndex)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates the throwing of a piece to the next available waiting node.
|
||||||
|
*
|
||||||
|
* @param uuid the UUID of the piece to animate
|
||||||
|
*/
|
||||||
|
public void throwPieceAnim(UUID uuid){
|
||||||
|
pieces.get(uuid).getSpatial().addControl(new MoveControl(
|
||||||
|
pieces.get(uuid).getLocation(),
|
||||||
|
getNextWaitingNode(pieceColor.get(uuid)).getLocation(),
|
||||||
|
()->throwPiece(uuid)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Animates the swapping of two pieces by swapping their positions and rotations.
|
||||||
|
*
|
||||||
|
* @param piece1 the UUID of the first piece
|
||||||
|
* @param piece2 the UUID of the second piece
|
||||||
|
*/
|
||||||
|
public void swapPieceAnim(UUID piece1, UUID piece2){
|
||||||
|
PieceControl piece1Control = pieces.get(piece1);
|
||||||
|
PieceControl piece2Control = pieces.get(piece2);
|
||||||
|
|
||||||
|
Vector3f loc1 = piece1Control.getLocation().clone();
|
||||||
|
Vector3f loc2 = piece2Control.getLocation().clone();
|
||||||
|
float rot1 = piece1Control.getRotation();
|
||||||
|
float rot2 = piece2Control.getRotation();
|
||||||
|
|
||||||
|
piece1Control.getSpatial().addControl(new MoveControl(
|
||||||
|
piece1Control.getLocation().clone(),
|
||||||
|
piece2Control.getLocation().clone(),
|
||||||
|
()->{}
|
||||||
|
));
|
||||||
|
piece2Control.getSpatial().addControl(new MoveControl(
|
||||||
|
piece2Control.getLocation().clone(),
|
||||||
|
piece1Control.getLocation().clone(),
|
||||||
|
()->swapPieces(piece1Control,piece2Control,loc1,rot1,loc2,rot2)
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieves the next available waiting node for the specified color.
|
||||||
|
*
|
||||||
|
* @param color the color of the player to get the next waiting node for
|
||||||
|
* @return the next available NodeControl for the specified color
|
||||||
|
* @throws IllegalStateException if no available waiting nodes are found for the color
|
||||||
|
*/
|
||||||
|
private NodeControl getNextWaitingNode(Color color) {
|
||||||
|
List<NodeControl> nodes = waitingNodesMap.get(color);
|
||||||
|
|
||||||
|
if (nodes == null || nodes.isEmpty()) {
|
||||||
|
throw new IllegalStateException("Keine verfügbaren Warteschleifen-Knoten für die Farbe " + color);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (NodeControl node : nodes) {
|
||||||
|
if (!waitingNodes.getOrDefault(color, new HashMap<>()).containsValue(node)) {
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
throw new IllegalStateException("Keine freien Nodes im Wartebereich für die Farbe " + color);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,10 @@
|
|||||||
import pp.mdga.client.MdgaApp;
|
import pp.mdga.client.MdgaApp;
|
||||||
import pp.mdga.game.Color;
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles the camera position, rotation, and lighting effects for the game.
|
||||||
|
* Provides methods for camera initialization, updates based on user input, and shutdown operations.
|
||||||
|
*/
|
||||||
public class CameraHandler {
|
public class CameraHandler {
|
||||||
MdgaApp app;
|
MdgaApp app;
|
||||||
|
|
||||||
@@ -34,6 +38,12 @@ public class CameraHandler {
|
|||||||
private boolean init;
|
private boolean init;
|
||||||
private boolean initRot;
|
private boolean initRot;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor for the CameraHandler. Initializes the camera settings and lighting.
|
||||||
|
*
|
||||||
|
* @param app The main application instance that provides the camera and root node.
|
||||||
|
* @param fpp The FilterPostProcessor used for post-processing effects.
|
||||||
|
*/
|
||||||
public CameraHandler(MdgaApp app, FilterPostProcessor fpp) {
|
public CameraHandler(MdgaApp app, FilterPostProcessor fpp) {
|
||||||
init = false;
|
init = false;
|
||||||
initRot = false;
|
initRot = false;
|
||||||
@@ -61,6 +71,12 @@ public CameraHandler(MdgaApp app, FilterPostProcessor fpp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the camera with a specific color orientation.
|
||||||
|
* Adds lights, sky, and shadow filters to the scene.
|
||||||
|
*
|
||||||
|
* @param ownColor The color that defines the initial camera view angle.
|
||||||
|
*/
|
||||||
public void init(Color ownColor) {
|
public void init(Color ownColor) {
|
||||||
app.getRootNode().addLight(sun);
|
app.getRootNode().addLight(sun);
|
||||||
app.getRootNode().addLight(ambient);
|
app.getRootNode().addLight(ambient);
|
||||||
@@ -72,6 +88,10 @@ public void init(Color ownColor) {
|
|||||||
app.getInputSynchronize().setRotation(getInitAngleByColor(ownColor)*2);
|
app.getInputSynchronize().setRotation(getInitAngleByColor(ownColor)*2);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Shuts down the camera handler by removing all lights, sky, and filters,
|
||||||
|
* and resets the camera position and rotation to its default state.
|
||||||
|
*/
|
||||||
public void shutdown() {
|
public void shutdown() {
|
||||||
app.getRootNode().removeLight(sun);
|
app.getRootNode().removeLight(sun);
|
||||||
app.getRootNode().removeLight(ambient);
|
app.getRootNode().removeLight(ambient);
|
||||||
@@ -84,6 +104,13 @@ public void shutdown() {
|
|||||||
fpp.removeFilter(dlsf);
|
fpp.removeFilter(dlsf);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the camera position and rotation based on user input (scroll and rotation).
|
||||||
|
* Adjusts the vertical angle and radius based on zoom and rotation values.
|
||||||
|
*
|
||||||
|
* @param scroll The scroll input, determining zoom level.
|
||||||
|
* @param rotation The rotation input, determining camera orientation.
|
||||||
|
*/
|
||||||
public void update(float scroll, float rotation) {
|
public void update(float scroll, float rotation) {
|
||||||
if(!init) return;
|
if(!init) return;
|
||||||
float scrollValue = Math.max(0, Math.min(scroll, 100));
|
float scrollValue = Math.max(0, Math.min(scroll, 100));
|
||||||
@@ -117,6 +144,12 @@ public void update(float scroll, float rotation) {
|
|||||||
app.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Z);
|
app.getCamera().lookAt(Vector3f.ZERO, Vector3f.UNIT_Z);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the camera angle based on the specified color.
|
||||||
|
*
|
||||||
|
* @param color The color used to determine the camera angle.
|
||||||
|
* @return The camera angle in degrees.
|
||||||
|
*/
|
||||||
private float getAngleByColor(Color color){
|
private float getAngleByColor(Color color){
|
||||||
return switch (color){
|
return switch (color){
|
||||||
case ARMY -> 0;
|
case ARMY -> 0;
|
||||||
@@ -127,6 +160,12 @@ private float getAngleByColor(Color color){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the initial camera angle based on the specified color.
|
||||||
|
*
|
||||||
|
* @param color The color used to determine the camera angle.
|
||||||
|
* @return The initial camera angle in degrees.
|
||||||
|
*/
|
||||||
private float getInitAngleByColor(Color color){
|
private float getInitAngleByColor(Color color){
|
||||||
return (getAngleByColor(color) + 180) % 360;
|
return (getAngleByColor(color) + 180) % 360;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,11 +10,27 @@
|
|||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A utility class for loading and parsing map data from a file.
|
||||||
|
* The map contains asset names and coordinates for objects placed on the map.
|
||||||
|
*/
|
||||||
class MapLoader {
|
class MapLoader {
|
||||||
|
/**
|
||||||
|
* Private constructor to prevent instantiation.
|
||||||
|
*/
|
||||||
private MapLoader() {
|
private MapLoader() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Loads a map file and parses its contents into a list of assets and their positions.
|
||||||
|
* Each line in the map file defines an asset, its coordinates, and its rotation.
|
||||||
|
*
|
||||||
|
* @param mapName The name of the map file to load. The file is expected to be located in the resources directory.
|
||||||
|
* @return A list of {@link AssetOnMap} objects representing the assets placed on the map.
|
||||||
|
* @throws IOException If an error occurs while reading the map file.
|
||||||
|
* @throws IllegalArgumentException If the map file contains invalid data.
|
||||||
|
*/
|
||||||
public static List<AssetOnMap> loadMap(String mapName) {
|
public static List<AssetOnMap> loadMap(String mapName) {
|
||||||
List<AssetOnMap> assetsOnMap = new ArrayList<>();
|
List<AssetOnMap> assetsOnMap = new ArrayList<>();
|
||||||
|
|
||||||
@@ -60,6 +76,13 @@ public static List<AssetOnMap> loadMap(String mapName) {
|
|||||||
return assetsOnMap;
|
return assetsOnMap;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the corresponding {@link Asset} for a given asset name.
|
||||||
|
*
|
||||||
|
* @param assetName The name of the asset to load.
|
||||||
|
* @return The {@link Asset} associated with the given name.
|
||||||
|
* @throws IllegalStateException If the asset name is unrecognized.
|
||||||
|
*/
|
||||||
private static Asset getLoadedAsset(String assetName) {
|
private static Asset getLoadedAsset(String assetName) {
|
||||||
return switch (assetName) {
|
return switch (assetName) {
|
||||||
case "lw" -> Asset.lw;
|
case "lw" -> Asset.lw;
|
||||||
|
|||||||
@@ -8,19 +8,40 @@
|
|||||||
import com.jme3.scene.control.AbstractControl;
|
import com.jme3.scene.control.AbstractControl;
|
||||||
import pp.mdga.client.MdgaApp;
|
import pp.mdga.client.MdgaApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A control that adds highlighting functionality to a node in the game.
|
||||||
|
* This class extends {@link OutlineControl} to add an outline effect when the node is highlighted.
|
||||||
|
*/
|
||||||
public class NodeControl extends OutlineControl {
|
public class NodeControl extends OutlineControl {
|
||||||
|
|
||||||
private static final ColorRGBA OUTLINE_HIGHLIGHT_COLOR = ColorRGBA.White;
|
private static final ColorRGBA OUTLINE_HIGHLIGHT_COLOR = ColorRGBA.White;
|
||||||
private static final int OUTLINE_HIGHLIGHT_WIDTH = 6;
|
private static final int OUTLINE_HIGHLIGHT_WIDTH = 6;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a {@link NodeControl} with the specified application and post processor.
|
||||||
|
* This constructor sets up the necessary elements for highlighting functionality.
|
||||||
|
*
|
||||||
|
* @param app The {@link MdgaApp} instance to use for the application context.
|
||||||
|
* @param fpp The {@link FilterPostProcessor} to apply post-processing effects.
|
||||||
|
*/
|
||||||
public NodeControl(MdgaApp app, FilterPostProcessor fpp) {
|
public NodeControl(MdgaApp app, FilterPostProcessor fpp) {
|
||||||
super(app, fpp);
|
super(app, fpp);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Returns the location of the node in 3D space.
|
||||||
|
* This is the node's local translation in the scene.
|
||||||
|
*
|
||||||
|
* @return The {@link Vector3f} representing the node's location.
|
||||||
|
*/
|
||||||
public Vector3f getLocation(){
|
public Vector3f getLocation(){
|
||||||
return this.getSpatial().getLocalTranslation();
|
return this.getSpatial().getLocalTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlights the node by applying an outline effect.
|
||||||
|
* The outline color and width are predefined as white and 6, respectively.
|
||||||
|
*/
|
||||||
public void highlight() {
|
public void highlight() {
|
||||||
super.outline(OUTLINE_HIGHLIGHT_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
|
super.outline(OUTLINE_HIGHLIGHT_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3,16 +3,19 @@
|
|||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
import com.jme3.post.FilterPostProcessor;
|
import com.jme3.post.FilterPostProcessor;
|
||||||
import com.jme3.renderer.Camera;
|
import com.jme3.renderer.Camera;
|
||||||
import com.jme3.renderer.RenderManager;
|
|
||||||
import com.jme3.renderer.ViewPort;
|
|
||||||
import com.jme3.scene.Spatial;
|
|
||||||
import com.jme3.scene.control.AbstractControl;
|
|
||||||
import pp.mdga.client.MdgaApp;
|
import pp.mdga.client.MdgaApp;
|
||||||
import pp.mdga.client.board.outline.SelectObjectOutliner;
|
import pp.mdga.client.InitControl;
|
||||||
|
import pp.mdga.client.outline.SelectObjectOutliner;
|
||||||
|
|
||||||
public class OutlineControl extends AbstractControl {
|
/**
|
||||||
private static final int THICKNESS_DEFAULT = 6;
|
* A control that provides outline functionality to a spatial object.
|
||||||
|
* This class is responsible for adding an outline effect to a spatial
|
||||||
|
* object, allowing it to be highlighted or deselected.
|
||||||
|
*/
|
||||||
|
public class OutlineControl extends InitControl {
|
||||||
|
/** The {@link SelectObjectOutliner} responsible for managing the outline effect. */
|
||||||
private final SelectObjectOutliner outlineOwn;
|
private final SelectObjectOutliner outlineOwn;
|
||||||
|
private static final int THICKNESS_DEFAULT = 6;
|
||||||
private MdgaApp app;
|
private MdgaApp app;
|
||||||
|
|
||||||
|
|
||||||
@@ -31,44 +34,33 @@ public OutlineControl(MdgaApp app, FilterPostProcessor fpp, Camera cam, int thic
|
|||||||
outlineOwn = new SelectObjectOutliner(thickness, fpp, app.getRenderManager(), app.getAssetManager(), cam, app);
|
outlineOwn = new SelectObjectOutliner(thickness, fpp, app.getRenderManager(), app.getAssetManager(), cam, app);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies an outline to the spatial object with the given color.
|
||||||
|
*
|
||||||
|
* @param color The {@link ColorRGBA} representing the color of the outline.
|
||||||
|
*/
|
||||||
public void outline(ColorRGBA color){
|
public void outline(ColorRGBA color){
|
||||||
outlineOwn.select(spatial, color);
|
outlineOwn.select(spatial, color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies an outline to the spatial object with the given color and width.
|
||||||
|
*
|
||||||
|
* @param color The {@link ColorRGBA} representing the color of the outline.
|
||||||
|
* @param width The width of the outline.
|
||||||
|
*/
|
||||||
public void outline(ColorRGBA color, int width){
|
public void outline(ColorRGBA color, int width){
|
||||||
deOutline();
|
deOutline();
|
||||||
outlineOwn.select(spatial, color, width);
|
outlineOwn.select(spatial, color, width);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the outline effect from the spatial object.
|
||||||
|
*/
|
||||||
public void deOutline(){
|
public void deOutline(){
|
||||||
outlineOwn.deselect(spatial);
|
outlineOwn.deselect(spatial);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void controlUpdate(float tpf) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void controlRender(RenderManager rm, ViewPort vp) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
public void initSpatial(){
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpatial(Spatial spatial){
|
|
||||||
if(this.spatial == null && spatial != null){
|
|
||||||
super.setSpatial(spatial);
|
|
||||||
initSpatial();
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
super.setSpatial(spatial);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public MdgaApp getApp() {
|
public MdgaApp getApp() {
|
||||||
return app;
|
return app;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -14,6 +14,12 @@
|
|||||||
import pp.mdga.client.Asset;
|
import pp.mdga.client.Asset;
|
||||||
import pp.mdga.client.MdgaApp;
|
import pp.mdga.client.MdgaApp;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A control that manages the behavior and properties of a game piece, such as its rotation,
|
||||||
|
* position, shield activation, and highlighting. This class extends {@link OutlineControl}
|
||||||
|
* to provide outline functionality and includes additional features like shield effects,
|
||||||
|
* hover states, and selection states.
|
||||||
|
*/
|
||||||
public class PieceControl extends OutlineControl {
|
public class PieceControl extends OutlineControl {
|
||||||
private final float initRotation;
|
private final float initRotation;
|
||||||
private final AssetManager assetManager;
|
private final AssetManager assetManager;
|
||||||
@@ -43,7 +49,15 @@ public class PieceControl extends OutlineControl {
|
|||||||
private boolean selectable;
|
private boolean selectable;
|
||||||
private boolean select;
|
private boolean select;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a {@link PieceControl} with the specified initial rotation, asset manager,
|
||||||
|
* application, and post-processor.
|
||||||
|
*
|
||||||
|
* @param initRotation The initial rotation of the piece in degrees.
|
||||||
|
* @param assetManager The {@link AssetManager} used for loading models and materials.
|
||||||
|
* @param app The {@link MdgaApp} instance to use for the application context.
|
||||||
|
* @param fpp The {@link FilterPostProcessor} to apply post-processing effects.
|
||||||
|
*/
|
||||||
public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app, FilterPostProcessor fpp){
|
public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app, FilterPostProcessor fpp){
|
||||||
super(app, fpp);
|
super(app, fpp);
|
||||||
this.parentNode = new Node();
|
this.parentNode = new Node();
|
||||||
@@ -59,10 +73,20 @@ public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app,
|
|||||||
select = false;
|
select = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current rotation of the piece in degrees.
|
||||||
|
*
|
||||||
|
* @return The rotation of the piece in degrees.
|
||||||
|
*/
|
||||||
public float getRotation() {
|
public float getRotation() {
|
||||||
return (float) Math.toDegrees(spatial.getLocalRotation().toAngleAxis(new Vector3f(0,0,1)));
|
return (float) Math.toDegrees(spatial.getLocalRotation().toAngleAxis(new Vector3f(0,0,1)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the rotation of the piece to the specified value in degrees.
|
||||||
|
*
|
||||||
|
* @param rot The rotation in degrees to set.
|
||||||
|
*/
|
||||||
public void setRotation(float rot){
|
public void setRotation(float rot){
|
||||||
if(rot < 0) rot =- 360;
|
if(rot < 0) rot =- 360;
|
||||||
|
|
||||||
@@ -71,10 +95,20 @@ public void setRotation(float rot){
|
|||||||
spatial.setLocalRotation(quaternion);
|
spatial.setLocalRotation(quaternion);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the current location (position) of the piece.
|
||||||
|
*
|
||||||
|
* @return The location of the piece as a {@link Vector3f}.
|
||||||
|
*/
|
||||||
public Vector3f getLocation(){
|
public Vector3f getLocation(){
|
||||||
return spatial.getLocalTranslation();
|
return spatial.getLocalTranslation();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Updates the piece control every frame. If the shield is active, it will rotate.
|
||||||
|
*
|
||||||
|
* @param delta The time difference between frames (time per frame).
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
protected void controlUpdate(float delta) {
|
protected void controlUpdate(float delta) {
|
||||||
if(shieldRing != null){
|
if(shieldRing != null){
|
||||||
@@ -82,10 +116,19 @@ protected void controlUpdate(float delta) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets the location (position) of the piece.
|
||||||
|
*
|
||||||
|
* @param loc The location to set as a {@link Vector3f}.
|
||||||
|
*/
|
||||||
public void setLocation(Vector3f loc){
|
public void setLocation(Vector3f loc){
|
||||||
this.spatial.setLocalTranslation(loc);
|
this.spatial.setLocalTranslation(loc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Initializes the spatial object and sets its rotation.
|
||||||
|
* This also moves the spatial to a new parent node for organizational purposes.
|
||||||
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void initSpatial(){
|
public void initSpatial(){
|
||||||
setRotation(this.initRotation);
|
setRotation(this.initRotation);
|
||||||
@@ -101,6 +144,10 @@ public void rotateInit() {
|
|||||||
// rotate(rotation - initRotation);
|
// rotate(rotation - initRotation);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Activates the shield around the piece.
|
||||||
|
* This adds a visual shield effect in the form of a rotating ring.
|
||||||
|
*/
|
||||||
public void activateShield(){
|
public void activateShield(){
|
||||||
shieldRing = assetManager.loadModel(Asset.shieldRing.getModelPath());
|
shieldRing = assetManager.loadModel(Asset.shieldRing.getModelPath());
|
||||||
shieldRing.scale(1f);
|
shieldRing.scale(1f);
|
||||||
@@ -115,11 +162,18 @@ public void activateShield(){
|
|||||||
parentNode.attachChild(shieldRing);
|
parentNode.attachChild(shieldRing);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deactivates the shield by removing the shield ring from the scene.
|
||||||
|
*/
|
||||||
|
|
||||||
public void deactivateShield(){
|
public void deactivateShield(){
|
||||||
parentNode.detachChild(shieldRing);
|
parentNode.detachChild(shieldRing);
|
||||||
shieldRing = null;
|
shieldRing = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Suppresses the shield, changing its color to a suppressed state.
|
||||||
|
*/
|
||||||
public void suppressShield(){
|
public void suppressShield(){
|
||||||
assert(shieldRing != null) : "PieceControl: shieldRing is not set";
|
assert(shieldRing != null) : "PieceControl: shieldRing is not set";
|
||||||
shieldMat.setColor("Color", SHIELD_SUPPRESSED_COLOR);
|
shieldMat.setColor("Color", SHIELD_SUPPRESSED_COLOR);
|
||||||
@@ -133,22 +187,36 @@ public Material getMaterial(){
|
|||||||
return ((Geometry) getSpatial()).getMaterial();
|
return ((Geometry) getSpatial()).getMaterial();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Highlights the piece with the appropriate outline color based on whether it is an enemy or not.
|
||||||
|
*
|
||||||
|
* @param enemy True if the piece is an enemy, false if it is owned by the player.
|
||||||
|
*/
|
||||||
public void highlight(boolean enemy) {
|
public void highlight(boolean enemy) {
|
||||||
this.enemy = enemy;
|
this.enemy = enemy;
|
||||||
highlight = true;
|
highlight = true;
|
||||||
super.outline(enemy ? OUTLINE_ENEMY_COLOR : OUTLINE_OWN_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
|
super.outline(enemy ? OUTLINE_ENEMY_COLOR : OUTLINE_OWN_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the highlight effect from the piece.
|
||||||
|
*/
|
||||||
public void unHighlight(){
|
public void unHighlight(){
|
||||||
highlight = false;
|
highlight = false;
|
||||||
deOutline();
|
deOutline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Applies a hover effect on the piece if it is hoverable.
|
||||||
|
*/
|
||||||
public void hover(){
|
public void hover(){
|
||||||
if(!hoverable) return;
|
if(!hoverable) return;
|
||||||
super.outline(enemy ? OUTLINE_ENEMY_HOVER_COLOR : OUTLINE_OWN_HOVER_COLOR, OUTLINE_HOVER_WIDTH);
|
super.outline(enemy ? OUTLINE_ENEMY_HOVER_COLOR : OUTLINE_OWN_HOVER_COLOR, OUTLINE_HOVER_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Removes the hover effect from the piece.
|
||||||
|
*/
|
||||||
public void hoverOff(){
|
public void hoverOff(){
|
||||||
if(!hoverable) return;
|
if(!hoverable) return;
|
||||||
|
|
||||||
@@ -157,28 +225,56 @@ public void hoverOff(){
|
|||||||
else deOutline();
|
else deOutline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deselects the piece and removes the selection outline. If the piece was highlighted,
|
||||||
|
* it will be re-highlighted. Otherwise, the outline is removed.
|
||||||
|
*/
|
||||||
public void unSelect(){
|
public void unSelect(){
|
||||||
select = false;
|
select = false;
|
||||||
if(highlight) highlight(enemy);
|
if(highlight) highlight(enemy);
|
||||||
else deOutline();
|
else deOutline();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Selects the piece and applies the selection outline. If the piece is an enemy, it will
|
||||||
|
* be outlined with the enemy selection color; otherwise, the own selection color will be used.
|
||||||
|
*/
|
||||||
public void select(){
|
public void select(){
|
||||||
if(!selectable) return;
|
if(!selectable) return;
|
||||||
select = true;
|
select = true;
|
||||||
super.outline(enemy ? OUTLINE_ENEMY_SELECT_COLOR : OUTLINE_OWN_SELECT_COLOR, OUTLINE_SELECT_WIDTH);
|
super.outline(enemy ? OUTLINE_ENEMY_SELECT_COLOR : OUTLINE_OWN_SELECT_COLOR, OUTLINE_SELECT_WIDTH);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the piece is selectable.
|
||||||
|
*
|
||||||
|
* @param selectable True if the piece can be selected, false otherwise.
|
||||||
|
*/
|
||||||
public void setSelectable(boolean selectable){
|
public void setSelectable(boolean selectable){
|
||||||
this.selectable = selectable;
|
this.selectable = selectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the piece is selected.
|
||||||
|
*
|
||||||
|
* @return True if the piece is selected, false otherwise.
|
||||||
|
*/
|
||||||
public boolean isSelected() { return select; }
|
public boolean isSelected() { return select; }
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Checks if the piece is selectable.
|
||||||
|
*
|
||||||
|
* @return True if the piece is selectable, false otherwise.
|
||||||
|
*/
|
||||||
public boolean isSelectable() {
|
public boolean isSelectable() {
|
||||||
return selectable;
|
return selectable;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Sets whether the piece is hoverable.
|
||||||
|
*
|
||||||
|
* @param hoverable True if the piece can be hovered over, false otherwise.
|
||||||
|
*/
|
||||||
public void setHoverable(boolean hoverable) {
|
public void setHoverable(boolean hoverable) {
|
||||||
this.hoverable = hoverable;
|
this.hoverable = hoverable;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,5 +0,0 @@
|
|||||||
package pp.mdga.client.board;
|
|
||||||
|
|
||||||
class PileControl {
|
|
||||||
|
|
||||||
}
|
|
||||||
@@ -1,12 +0,0 @@
|
|||||||
package pp.mdga.client.board;
|
|
||||||
|
|
||||||
public enum Rotation {
|
|
||||||
UP,
|
|
||||||
RIGHT,
|
|
||||||
DOWN,
|
|
||||||
LEFT,
|
|
||||||
UP_LEFT,
|
|
||||||
UP_RIGHT,
|
|
||||||
DOWN_RIGHT,
|
|
||||||
DOWN_LEFT
|
|
||||||
}
|
|
||||||
@@ -7,22 +7,23 @@
|
|||||||
import com.jme3.math.Vector3f;
|
import com.jme3.math.Vector3f;
|
||||||
import com.jme3.scene.Node;
|
import com.jme3.scene.Node;
|
||||||
import com.jme3.system.AppSettings;
|
import com.jme3.system.AppSettings;
|
||||||
import pp.mdga.client.Asset;
|
import pp.mdga.client.animation.ZoomControl;
|
||||||
import pp.mdga.game.Color;
|
import pp.mdga.game.Color;
|
||||||
|
|
||||||
public class ActionTextHandler {
|
class ActionTextHandler {
|
||||||
private Node root;
|
private Node root;
|
||||||
private BitmapFont font;
|
private BitmapFont font;
|
||||||
private AppSettings appSettings;
|
private AppSettings appSettings;
|
||||||
|
private int ranking;
|
||||||
|
|
||||||
public ActionTextHandler(Node guiNode, AssetManager assetManager, AppSettings appSettings){
|
ActionTextHandler(Node guiNode, AssetManager assetManager, AppSettings appSettings){
|
||||||
root = new Node("actionTextRoot");
|
root = new Node("actionTextRoot");
|
||||||
guiNode.attachChild(root);
|
guiNode.attachChild(root);
|
||||||
|
|
||||||
root.setLocalTranslation(center(appSettings.getWidth(), appSettings.getHeight(), Vector3f.ZERO));
|
root.setLocalTranslation(center(appSettings.getWidth(), appSettings.getHeight(), Vector3f.ZERO));
|
||||||
font = assetManager.loadFont("Fonts/Gunplay.fnt");
|
font = assetManager.loadFont("Fonts/Gunplay.fnt");
|
||||||
this.appSettings = appSettings;
|
this.appSettings = appSettings;
|
||||||
|
ranking = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
private Node createTextWithSpacing(String[] textArr, float spacing, float size, ColorRGBA[] colorArr) {
|
private Node createTextWithSpacing(String[] textArr, float spacing, float size, ColorRGBA[] colorArr) {
|
||||||
@@ -74,48 +75,48 @@ private Vector3f centerText(float width, float height, Vector3f pos){
|
|||||||
return center(-width, height, pos);
|
return center(-width, height, pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void activePlayer(String name, Color color){
|
void activePlayer(String name, Color color){
|
||||||
createTopText(new String[]{name," ist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
createTopText(new String[]{name," ist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ownActive(Color color){
|
void ownActive(Color color){
|
||||||
createTopText(new String[]{"Du"," bist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
createTopText(new String[]{"Du"," bist dran"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void diceNum(int diceNum, String name, Color color){
|
void diceNum(int diceNum, String name, Color color){
|
||||||
createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0);
|
createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0);
|
||||||
|
|
||||||
createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 100);
|
createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 100);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void diceNumMult(int diceNum,int mult, String name, Color color){
|
void diceNumMult(int diceNum,int mult, String name, Color color){
|
||||||
createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0);
|
createTopText(new String[]{name," würfelt:"}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0);
|
||||||
|
|
||||||
createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 100);
|
createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 100);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ownDice(int diceNum){
|
void ownDice(int diceNum){
|
||||||
createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 0);
|
createTopText(String.valueOf(diceNum), 10, 100, ColorRGBA.White, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ownDiceMult(int diceNum, int mult){
|
void ownDiceMult(int diceNum, int mult){
|
||||||
createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 0);
|
createTopText(new String[]{String.valueOf(diceNum), " x" + mult + " = " + (diceNum*mult)}, 20, 100, new ColorRGBA[]{ColorRGBA.White,ColorRGBA.Red}, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawCard(String name, Color color){
|
void drawCard(String name, Color color){
|
||||||
createTopText(new String[]{name," erhält eine Bonuskarte"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
createTopText(new String[]{name," erhält eine Bonuskarte"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void drawCardOwn(Color color){
|
void drawCardOwn(Color color){
|
||||||
createTopText(new String[]{"Du"," erhälst eine Bonuskarte"}, 5,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
createTopText(new String[]{"Du"," erhälst eine Bonuskarte"}, 5,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishText(String name, Color color){
|
void finishText(String name, Color color){
|
||||||
createTopText(new String[]{name," ist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
createTopText(new String[]{name," ist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void finishTextOwn(Color color){
|
void finishTextOwn(Color color){
|
||||||
createTopText(new String[]{"Du", " bist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
createTopText(new String[]{"Du", " bist fertig!"}, 7,70, new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, 0).addControl(new ZoomControl());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -131,9 +132,25 @@ private ColorRGBA playerColorToColorRGBA(Color color){
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hide(){
|
void hide(){
|
||||||
root.detachAllChildren();
|
ranking = 0;
|
||||||
|
root.detachAllChildren();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
float paddingRanked = 100;
|
||||||
|
|
||||||
|
void rollRankingResult(String name, Color color, int eye){
|
||||||
|
createTopText(new String[]{name,": "+eye}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, paddingRanked*ranking);
|
||||||
|
ranking++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void rollRankingResultOwn(Color color, int eye){
|
||||||
|
createTopText(new String[]{"Du",": "+eye}, 10,90,new ColorRGBA[]{playerColorToColorRGBA(color),ColorRGBA.White}, paddingRanked*ranking);
|
||||||
|
ranking++;
|
||||||
|
}
|
||||||
|
|
||||||
|
void diceNow(){
|
||||||
|
createTopText("Klicke zum Würfeln", 5, 80, ColorRGBA.White, 0);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,6 +10,7 @@
|
|||||||
import com.jme3.texture.Texture2D;
|
import com.jme3.texture.Texture2D;
|
||||||
import pp.mdga.client.Asset;
|
import pp.mdga.client.Asset;
|
||||||
import pp.mdga.client.MdgaApp;
|
import pp.mdga.client.MdgaApp;
|
||||||
|
import pp.mdga.client.animation.SymbolControl;
|
||||||
import pp.mdga.game.BonusCard;
|
import pp.mdga.game.BonusCard;
|
||||||
|
|
||||||
import java.util.*;
|
import java.util.*;
|
||||||
|
|||||||
@@ -67,6 +67,7 @@ public void showRolledDice(int rollNum, Color color) {
|
|||||||
|
|
||||||
public void showDice() {
|
public void showDice() {
|
||||||
cardLayerHandler.showDice();
|
cardLayerHandler.showDice();
|
||||||
|
actionTextHandler.diceNow();
|
||||||
}
|
}
|
||||||
|
|
||||||
public void hideDice() {
|
public void hideDice() {
|
||||||
@@ -134,5 +135,10 @@ public void finish(Color color){
|
|||||||
else actionTextHandler.finishText(playerNameHandler.getName(color), color);
|
else actionTextHandler.finishText(playerNameHandler.getName(color), color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void rollRankingResult(Color color, int eye){
|
||||||
|
if(ownColor == color) actionTextHandler.rollRankingResultOwn(color, eye);
|
||||||
|
else actionTextHandler.rollRankingResult(playerNameHandler.getName(color), color, eye);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -120,6 +120,7 @@ public void setActivePlayer(Color color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public String getName(Color color){
|
public String getName(Color color){
|
||||||
|
if(!colorNameMap.containsKey(color)) throw new RuntimeException("color is not in colorNameMap");
|
||||||
return colorNameMap.get(color);
|
return colorNameMap.get(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -1,84 +0,0 @@
|
|||||||
package pp.mdga.client.gui;
|
|
||||||
|
|
||||||
import com.jme3.renderer.RenderManager;
|
|
||||||
import com.jme3.renderer.ViewPort;
|
|
||||||
import com.jme3.scene.Spatial;
|
|
||||||
import com.jme3.scene.control.AbstractControl;
|
|
||||||
|
|
||||||
public class ZoomControl extends AbstractControl {
|
|
||||||
private boolean zoomingIn = false;
|
|
||||||
private boolean zoomingOut = false;
|
|
||||||
private float progress = 0;
|
|
||||||
private float zoomSpeed = 1f;
|
|
||||||
private float zoomFactor = 1f;
|
|
||||||
|
|
||||||
public ZoomControl() {
|
|
||||||
}
|
|
||||||
|
|
||||||
public ZoomControl(float speed) {
|
|
||||||
zoomSpeed = speed;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
public void setSpatial(Spatial spatial) {
|
|
||||||
if (this.spatial == null && spatial != null) {
|
|
||||||
super.setSpatial(spatial);
|
|
||||||
initSpatial();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void initSpatial() {
|
|
||||||
zoomingIn = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void controlUpdate(float tpf) {
|
|
||||||
if (zoomingIn) {
|
|
||||||
progress += tpf * zoomSpeed;
|
|
||||||
if (progress > 1) progress = 1;
|
|
||||||
spatial.setLocalScale(lerp(0, zoomFactor, easeOut(progress)));
|
|
||||||
if (progress >= 1) {
|
|
||||||
zoomingIn = false;
|
|
||||||
zoomingOut = true;
|
|
||||||
progress = 0;
|
|
||||||
}
|
|
||||||
} else if (zoomingOut) {
|
|
||||||
progress += tpf * zoomSpeed;
|
|
||||||
spatial.setLocalScale(lerp(zoomFactor, 0, easeIn(progress)));
|
|
||||||
if (progress > 1) {
|
|
||||||
zoomingOut = false;
|
|
||||||
end();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void end() {
|
|
||||||
spatial.removeFromParent();
|
|
||||||
spatial.removeControl(this);
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
|
||||||
protected void controlRender(RenderManager rm, ViewPort vp) {
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private static float lerp(float start, float end, float t) {
|
|
||||||
return (1 - t) * start + t * end;
|
|
||||||
}
|
|
||||||
|
|
||||||
// private static float easeOut(float t) {
|
|
||||||
// return (float) Math.sqrt(1 - Math.pow(t - 1, 2));
|
|
||||||
// }
|
|
||||||
private float easeOut(float x) {
|
|
||||||
return x == 1 ? 1 : (float) (1 - Math.pow(2, -10 * x));
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
// private float easeIn(float t) {
|
|
||||||
// return t * t * t * t;
|
|
||||||
// }
|
|
||||||
private float easeIn(float x) {
|
|
||||||
return x == 0 ? 0 : (float) Math.pow(2, 10 * x - 10);
|
|
||||||
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pp.mdga.client.board.outline;
|
package pp.mdga.client.outline;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pp.mdga.client.board.outline;
|
package pp.mdga.client.outline;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pp.mdga.client.board.outline;
|
package pp.mdga.client.outline;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.material.Material;
|
import com.jme3.material.Material;
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
package pp.mdga.client.board.outline;
|
package pp.mdga.client.outline;
|
||||||
|
|
||||||
import com.jme3.asset.AssetManager;
|
import com.jme3.asset.AssetManager;
|
||||||
import com.jme3.math.ColorRGBA;
|
import com.jme3.math.ColorRGBA;
|
||||||
@@ -2,6 +2,7 @@
|
|||||||
|
|
||||||
import com.jme3.network.*;
|
import com.jme3.network.*;
|
||||||
import com.jme3.network.serializing.Serializer;
|
import com.jme3.network.serializing.Serializer;
|
||||||
|
import com.jme3.network.serializing.serializers.EnumSerializer;
|
||||||
import pp.mdga.game.*;
|
import pp.mdga.game.*;
|
||||||
import pp.mdga.message.client.*;
|
import pp.mdga.message.client.*;
|
||||||
import pp.mdga.message.server.*;
|
import pp.mdga.message.server.*;
|
||||||
@@ -12,7 +13,6 @@
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
import java.lang.System.Logger;
|
import java.lang.System.Logger;
|
||||||
import java.lang.System.Logger.Level;
|
import java.lang.System.Logger.Level;
|
||||||
import java.net.InetAddress;
|
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.UUID;
|
import java.util.UUID;
|
||||||
import java.util.concurrent.BlockingQueue;
|
import java.util.concurrent.BlockingQueue;
|
||||||
@@ -130,6 +130,7 @@ private void initializeSerializables() {
|
|||||||
Serializer.registerClass(ReconnectBriefingMessage.class);
|
Serializer.registerClass(ReconnectBriefingMessage.class);
|
||||||
Serializer.registerClass(ResumeGameMessage.class);
|
Serializer.registerClass(ResumeGameMessage.class);
|
||||||
Serializer.registerClass(ServerStartGameMessage.class);
|
Serializer.registerClass(ServerStartGameMessage.class);
|
||||||
|
Serializer.registerClass(ShutdownMessage.class);
|
||||||
Serializer.registerClass(StartPieceMessage.class);
|
Serializer.registerClass(StartPieceMessage.class);
|
||||||
Serializer.registerClass(UpdateReadyMessage.class);
|
Serializer.registerClass(UpdateReadyMessage.class);
|
||||||
Serializer.registerClass(UpdateTSKMessage.class);
|
Serializer.registerClass(UpdateTSKMessage.class);
|
||||||
@@ -143,6 +144,8 @@ private void initializeSerializables() {
|
|||||||
Serializer.registerClass(StartNode.class);
|
Serializer.registerClass(StartNode.class);
|
||||||
Serializer.registerClass(PlayerData.class);
|
Serializer.registerClass(PlayerData.class);
|
||||||
Serializer.registerClass(HomeNode.class);
|
Serializer.registerClass(HomeNode.class);
|
||||||
|
Serializer.registerClass(PlayerDataMessage.class);
|
||||||
|
Serializer.registerClass(StartBriefingMessage.class);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void registerListeners() {
|
private void registerListeners() {
|
||||||
|
|||||||
@@ -64,6 +64,13 @@ public void onEnter() {
|
|||||||
app.getViewPort().addProcessor(fpp);
|
app.getViewPort().addProcessor(fpp);
|
||||||
|
|
||||||
app.getAcousticHandler().playSound(MdgaSound.START);
|
app.getAcousticHandler().playSound(MdgaSound.START);
|
||||||
|
|
||||||
|
// guiHandler.addPlayer(Color.AIRFORCE, "Cedric");
|
||||||
|
// guiHandler.addPlayer(Color.ARMY, "Ben");
|
||||||
|
// guiHandler.addPlayer(Color.CYBER, "Felix");
|
||||||
|
// guiHandler.addPlayer(Color.NAVY, "Daniel");
|
||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -228,7 +228,7 @@ private void toggleTsk(Color color) {
|
|||||||
app.getModelSynchronize().selectTsk(color);
|
app.getModelSynchronize().selectTsk(color);
|
||||||
break;
|
break;
|
||||||
case SELF:
|
case SELF:
|
||||||
app.getModelSynchronize().unselectTsk();
|
app.getModelSynchronize().unselectTsk(color);
|
||||||
break;
|
break;
|
||||||
case OTHER:
|
case OTHER:
|
||||||
//nothing
|
//nothing
|
||||||
|
|||||||
@@ -18,7 +18,7 @@ public CeremonyState(ClientState parent, ClientGameLogic logic) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
currentState = podiumState;
|
setState(podiumState);
|
||||||
logic.addNotification(createCeremonyNotification());
|
logic.addNotification(createCeremonyNotification());
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -28,7 +28,9 @@ public void exit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setState(CeremonyStates state){
|
public void setState(CeremonyStates state){
|
||||||
this.currentState.exit();
|
if(this.currentState != null){
|
||||||
|
this.currentState.exit();
|
||||||
|
}
|
||||||
state.enter();
|
state.enter();
|
||||||
currentState = state;
|
currentState = state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -190,6 +190,19 @@ public void received(ServerStartGameMessage msg) {
|
|||||||
state.received(msg);
|
state.received(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(ShutdownMessage msg) {state.received(msg);}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(StartBriefingMessage msg) {
|
||||||
|
state.received(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(PlayerDataMessage msg) {
|
||||||
|
state.received(msg);
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(StartPieceMessage msg) {
|
public void received(StartPieceMessage msg) {
|
||||||
state.received(msg);
|
state.received(msg);
|
||||||
@@ -236,6 +249,10 @@ public void selectTsk(Color color){
|
|||||||
state.selectTSK(color);
|
state.selectTSK(color);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void deselectTSK(Color color){
|
||||||
|
state.deselectTSK(color);
|
||||||
|
}
|
||||||
|
|
||||||
public void selectDice(){
|
public void selectDice(){
|
||||||
state.selectDice();
|
state.selectDice();
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -150,6 +150,9 @@ public void received(ServerStartGameMessage msg) {
|
|||||||
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(ShutdownMessage msg) {LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(StartPieceMessage msg) {
|
public void received(StartPieceMessage msg) {
|
||||||
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
||||||
@@ -180,6 +183,15 @@ public void received(WaitPieceMessage msg) {
|
|||||||
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(StartBriefingMessage msg) {
|
||||||
|
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void received(PlayerDataMessage msg) {
|
||||||
|
LOGGER.log(Level.DEBUG, "Received {0} not allowed.", msg);
|
||||||
|
}
|
||||||
|
|
||||||
public void selectPiece(Piece piece) {
|
public void selectPiece(Piece piece) {
|
||||||
LOGGER.log(Level.DEBUG, "Selecting piece not allowed.");
|
LOGGER.log(Level.DEBUG, "Selecting piece not allowed.");
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -30,13 +30,15 @@ public void exit(){
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter(){
|
public void enter(){
|
||||||
currentState = startDialogState;
|
setState(startDialogState);
|
||||||
ownPlayerID = 0;
|
ownPlayerID = 0;
|
||||||
ownPlayerName = null;
|
ownPlayerName = null;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void setState(DialogStates newState){
|
public void setState(DialogStates newState){
|
||||||
currentState.exit();
|
if(currentState != null){
|
||||||
|
currentState.exit();
|
||||||
|
}
|
||||||
newState.enter();
|
newState.enter();
|
||||||
currentState = newState;
|
currentState = newState;
|
||||||
}
|
}
|
||||||
@@ -69,11 +71,6 @@ public StartDialogState getStartDialog() {
|
|||||||
return startDialogState;
|
return startDialogState;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void startGame(){
|
|
||||||
exit();
|
|
||||||
logic.setState(logic.getGameState());
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectLeave(){
|
public void selectLeave(){
|
||||||
currentState.selectLeave();
|
currentState.selectLeave();
|
||||||
@@ -144,6 +141,16 @@ public void received(ServerStartGameMessage msg){
|
|||||||
currentState.received(msg);
|
currentState.received(msg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(PlayerDataMessage msg){
|
||||||
|
currentState.received(msg);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(StartBriefingMessage msg){
|
||||||
|
currentState.received(msg);
|
||||||
|
}
|
||||||
|
|
||||||
public DialogStates getState() {
|
public DialogStates getState() {
|
||||||
return currentState;
|
return currentState;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -27,7 +27,6 @@ public class GameState extends ClientState {
|
|||||||
*/
|
*/
|
||||||
public GameState(ClientState parent, ClientGameLogic logic) {
|
public GameState(ClientState parent, ClientGameLogic logic) {
|
||||||
super(parent, logic);
|
super(parent, logic);
|
||||||
state = determineStartPlayerState;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -35,7 +34,7 @@ public GameState(ClientState parent, ClientGameLogic logic) {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
|
this.setState(this.determineStartPlayerState);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -52,8 +51,10 @@ public void exit() {
|
|||||||
* @param newState the state to be set
|
* @param newState the state to be set
|
||||||
*/
|
*/
|
||||||
public void setState(GameStates newState){
|
public void setState(GameStates newState){
|
||||||
state.exit();
|
if(this.state != null){
|
||||||
state.enter();
|
this.state.exit();
|
||||||
|
}
|
||||||
|
newState.enter();
|
||||||
state = newState;
|
state = newState;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -10,7 +10,9 @@
|
|||||||
import pp.mdga.message.client.*;
|
import pp.mdga.message.client.*;
|
||||||
import pp.mdga.message.server.LobbyPlayerJoinedMessage;
|
import pp.mdga.message.server.LobbyPlayerJoinedMessage;
|
||||||
import pp.mdga.message.server.LobbyPlayerLeaveMessage;
|
import pp.mdga.message.server.LobbyPlayerLeaveMessage;
|
||||||
|
import pp.mdga.message.server.PlayerDataMessage;
|
||||||
import pp.mdga.message.server.ServerStartGameMessage;
|
import pp.mdga.message.server.ServerStartGameMessage;
|
||||||
|
import pp.mdga.message.server.StartBriefingMessage;
|
||||||
import pp.mdga.message.server.UpdateReadyMessage;
|
import pp.mdga.message.server.UpdateReadyMessage;
|
||||||
import pp.mdga.message.server.UpdateTSKMessage;
|
import pp.mdga.message.server.UpdateTSKMessage;
|
||||||
import pp.mdga.notification.*;
|
import pp.mdga.notification.*;
|
||||||
@@ -74,17 +76,26 @@ public void selectStart(){
|
|||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(ServerStartGameMessage msg){
|
public void received(StartBriefingMessage msg){
|
||||||
logic.getGame().setBoard(msg.getBoard());
|
logic.getGame().setBoard(msg.getBoard());
|
||||||
logic.addNotification(new GameNotification(logic.getGame().getPlayers().get(parent.getOwnPlayerId()).getColor()));
|
}
|
||||||
for(Map.Entry<Color, PlayerData> entry : msg.getBoard().getPlayerData().entrySet()){
|
|
||||||
List<UUID> pieceIds = new ArrayList<>();
|
public void received(PlayerDataMessage msg){
|
||||||
|
logic.getGame().getBoard().addPlayerData(msg.getColor(), msg.getPlayerData());
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void received(ServerStartGameMessage msg){
|
||||||
|
logic.addNotification(new GameNotification(logic.getGame().getPlayerById(parent.getOwnPlayerId()).getColor()));
|
||||||
|
for (Map.Entry<Color, PlayerData> entry : logic.getGame().getBoard().getPlayerData().entrySet()) {
|
||||||
|
List<UUID> pieceList = new ArrayList<>();
|
||||||
for(Piece piece : entry.getValue().getPieces()){
|
for(Piece piece : entry.getValue().getPieces()){
|
||||||
pieceIds.add(piece.getUuid());
|
System.out.println(piece.getUuid());
|
||||||
|
pieceList.add(piece.getUuid());
|
||||||
}
|
}
|
||||||
logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceIds, logic.getGame().getPlayerByColor(entry.getKey()).getName()));
|
logic.addNotification(new PlayerInGameNotification(entry.getKey(), pieceList , logic.getGame().getPlayerByColor(entry.getKey()).getName()));
|
||||||
}
|
}
|
||||||
parent.startGame();
|
logic.setState(logic.getGameState());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -95,15 +106,20 @@ public void received(LobbyPlayerJoinedMessage msg){
|
|||||||
if (msg.isHost() && msg.getId() == parent.getOwnPlayerId()){
|
if (msg.isHost() && msg.getId() == parent.getOwnPlayerId()){
|
||||||
logic.setHost(true);
|
logic.setHost(true);
|
||||||
}
|
}
|
||||||
logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), parent.getOwnPlayerId()== msg.getId()));
|
|
||||||
|
logic.addNotification(new TskSelectNotification(msg.getPlayer().getColor(), msg.getPlayer().getName(), msg.getPlayer().getName().equals(parent.getOwnPlayerName())));
|
||||||
logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer());
|
logic.getGame().getPlayers().put(msg.getId(), msg.getPlayer());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(UpdateTSKMessage msg){
|
public void received(UpdateTSKMessage msg){
|
||||||
logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor()));
|
if(msg.isTaken()) {
|
||||||
|
logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId()));
|
||||||
|
} else {
|
||||||
|
logic.addNotification(new TskUnselectNotification(logic.getGame().getPlayers().get(msg.getId()).getColor()));
|
||||||
|
}
|
||||||
|
|
||||||
logic.getGame().getPlayers().get(msg.getId()).setColor(msg.getColor());
|
logic.getGame().getPlayers().get(msg.getId()).setColor(msg.getColor());
|
||||||
logic.addNotification(new TskSelectNotification(msg.getColor(), logic.getGame().getPlayers().get(msg.getId()).getName(), parent.getOwnPlayerId()== msg.getId()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -14,34 +14,6 @@ public NetworkDialogState(ClientState parent, ClientGameLogic logic) {
|
|||||||
this.parent = (DialogsState) parent;
|
this.parent = (DialogsState) parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean checkIP(String IP){
|
|
||||||
String[] parts = IP.split("\\.");
|
|
||||||
|
|
||||||
// Step 2: Check if there are exactly 4 parts
|
|
||||||
if (parts.length != 4) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Step 3: Check each part for valid number
|
|
||||||
for (String part : parts) {
|
|
||||||
try {
|
|
||||||
// Step 4: Convert each part into a number
|
|
||||||
int num = Integer.parseInt(part);
|
|
||||||
|
|
||||||
// Step 5: Check whether the number lies in between 0 and 255
|
|
||||||
if (num < 0 || num > 255) {
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
} catch (NumberFormatException e) {
|
|
||||||
// If parsing fails, it's not a valid number
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// If all checks passed, return true
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ public DetermineStartPlayerState(ClientState parent, ClientGameLogic logic) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
state = rollRankingDiceState;
|
this.setState(this.rollRankingDiceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -34,7 +34,9 @@ public void exit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setState(DetermineStartPlayerStates state) {
|
public void setState(DetermineStartPlayerStates state) {
|
||||||
this.state.exit();
|
if(this.state != null){
|
||||||
|
this.state.exit();
|
||||||
|
}
|
||||||
state.enter();
|
state.enter();
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public TurnState(ClientState parent, ClientGameLogic logic) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
state = powerCardState;
|
this.setState(this.powerCardState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -40,7 +40,9 @@ public void exit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setState(TurnStates state){
|
public void setState(TurnStates state){
|
||||||
this.state.exit();
|
if(this.state != null){
|
||||||
|
this.state.exit();
|
||||||
|
}
|
||||||
state.enter();
|
state.enter();
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -6,6 +6,7 @@
|
|||||||
import pp.mdga.message.client.RequestDieMessage;
|
import pp.mdga.message.client.RequestDieMessage;
|
||||||
import pp.mdga.message.server.DieMessage;
|
import pp.mdga.message.server.DieMessage;
|
||||||
import pp.mdga.notification.DiceNowNotification;
|
import pp.mdga.notification.DiceNowNotification;
|
||||||
|
import pp.mdga.notification.RollDiceNotification;
|
||||||
|
|
||||||
public class RollRankingDiceState extends DetermineStartPlayerStates {
|
public class RollRankingDiceState extends DetermineStartPlayerStates {
|
||||||
|
|
||||||
@@ -23,16 +24,17 @@ public void enter() {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void exit() {
|
public void exit() {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void selectDice(){
|
public void selectDice(){
|
||||||
|
System.out.println("selectDice");
|
||||||
logic.send(new RequestDieMessage());
|
logic.send(new RequestDieMessage());
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void received(DieMessage msg){
|
public void received(DieMessage msg){
|
||||||
|
logic.addNotification(new RollDiceNotification(logic.getGame().getPlayerById(logic.getDialogs().getOwnPlayerId()).getColor(), msg.getDiceEye(),true));
|
||||||
parent.setState(parent.getWaitRanking());
|
parent.setState(parent.getWaitRanking());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,7 +24,7 @@ public ChoosePieceState(ClientState parent, ClientGameLogic logic) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
currentState = noPieceState;
|
this.setState(this.noPieceState);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -34,9 +34,11 @@ public void exit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setState(ChoosePieceStates state){
|
public void setState(ChoosePieceStates state){
|
||||||
currentState.exit();
|
if(currentState != null){
|
||||||
|
currentState.exit();
|
||||||
|
}
|
||||||
|
state.enter();
|
||||||
currentState = state;
|
currentState = state;
|
||||||
currentState.enter();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
|
|||||||
@@ -31,7 +31,7 @@ public PowerCardState(ClientState parent, ClientGameLogic logic) {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void enter() {
|
public void enter() {
|
||||||
state = choosePowerCardState;
|
this.setState(this.choosePowerCardState);
|
||||||
}
|
}
|
||||||
|
|
||||||
public void exit() {
|
public void exit() {
|
||||||
@@ -40,7 +40,9 @@ public void exit() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public void setState(PowerCardStates state) {
|
public void setState(PowerCardStates state) {
|
||||||
this.state.exit();
|
if(this.state != null){
|
||||||
|
this.state.exit();
|
||||||
|
}
|
||||||
state.enter();
|
state.enter();
|
||||||
this.state = state;
|
this.state = state;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -42,7 +42,9 @@ public Piece(Color color, PieceState state, int id) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private Piece() {
|
private Piece() {
|
||||||
color = null;
|
color = Color.NONE;
|
||||||
|
state = PieceState.WAITING;
|
||||||
|
shield = ShieldState.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,5 +1,7 @@
|
|||||||
package pp.mdga.game;
|
package pp.mdga.game;
|
||||||
|
|
||||||
|
import com.jme3.network.serializing.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the state of a piece.
|
* Represents the state of a piece.
|
||||||
*/
|
*/
|
||||||
@@ -19,5 +21,21 @@ public enum PieceState {
|
|||||||
/**
|
/**
|
||||||
* The piece is finished.
|
* The piece is finished.
|
||||||
*/
|
*/
|
||||||
HOMEFINISHED
|
HOMEFINISHED;
|
||||||
|
|
||||||
|
PieceState(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static PieceState getPieceStateByIndex(int index){
|
||||||
|
if (index < 0 || index >= values().length) {
|
||||||
|
throw new IllegalArgumentException("");
|
||||||
|
}
|
||||||
|
return values()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
public PieceState next() {
|
||||||
|
return values()[(ordinal() + 1) % values().length];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -43,10 +43,23 @@ public PlayerData(Color color) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructor.
|
||||||
|
*/
|
||||||
private PlayerData() {
|
private PlayerData() {
|
||||||
homeNodes = null;
|
homeNodes = new HomeNode[4];
|
||||||
waitingArea = null;
|
waitingArea = new Piece[4];
|
||||||
pieces = null;
|
pieces = new Piece[4];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* This method will be used to check if the player is finished.
|
||||||
|
* ToDo: Currently return always false. Implement logic!
|
||||||
|
*
|
||||||
|
* @return true or false.
|
||||||
|
*/
|
||||||
|
public boolean isFinished() {
|
||||||
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -1,8 +1,11 @@
|
|||||||
package pp.mdga.game;
|
package pp.mdga.game;
|
||||||
|
|
||||||
|
import com.jme3.network.serializing.Serializable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Represents the state of a piece's shield.
|
* Represents the state of a piece's shield.
|
||||||
*/
|
*/
|
||||||
|
@Serializable
|
||||||
public enum ShieldState {
|
public enum ShieldState {
|
||||||
/**
|
/**
|
||||||
* The shield is not active.
|
* The shield is not active.
|
||||||
@@ -15,5 +18,20 @@ public enum ShieldState {
|
|||||||
/**
|
/**
|
||||||
* The shield is suppressed, when the piece is on a start node.
|
* The shield is suppressed, when the piece is on a start node.
|
||||||
*/
|
*/
|
||||||
SUPPRESSED
|
SUPPRESSED;
|
||||||
|
|
||||||
|
ShieldState(){
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
public static ShieldState getShieldStateByIndex(int index){
|
||||||
|
if (index < 0 || index >= values().length) {
|
||||||
|
throw new IllegalArgumentException("");
|
||||||
|
}
|
||||||
|
return values()[index];
|
||||||
|
}
|
||||||
|
|
||||||
|
public ShieldState next() {
|
||||||
|
return values()[(ordinal() + 1) % values().length];
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ public StartNode(Color color) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
private StartNode() {
|
private StartNode() {
|
||||||
color = null;
|
color = Color.NONE;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -0,0 +1,40 @@
|
|||||||
|
package pp.mdga.message.server;
|
||||||
|
|
||||||
|
import com.jme3.network.serializing.Serializable;
|
||||||
|
import pp.mdga.game.Color;
|
||||||
|
import pp.mdga.game.PlayerData;
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class PlayerDataMessage extends ServerMessage{
|
||||||
|
|
||||||
|
private final PlayerData playerData;
|
||||||
|
private final Color color;
|
||||||
|
|
||||||
|
public PlayerDataMessage(PlayerData playerData, Color color){
|
||||||
|
super();
|
||||||
|
this.playerData = playerData;
|
||||||
|
this.color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
private PlayerDataMessage(){
|
||||||
|
this(null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(ServerInterpreter interpreter) {
|
||||||
|
interpreter.received(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfoTextKey() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
|
||||||
|
public PlayerData getPlayerData(){
|
||||||
|
return playerData;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Color getColor(){
|
||||||
|
return color;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -207,4 +207,15 @@ public interface ServerInterpreter {
|
|||||||
* @param msg the SelectPiece message received.
|
* @param msg the SelectPiece message received.
|
||||||
*/
|
*/
|
||||||
void received(SelectPieceMessage msg);
|
void received(SelectPieceMessage msg);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Handles a SelectTSK message received from the server.
|
||||||
|
*
|
||||||
|
* @param shutdownMessage the SelectTSK message received.
|
||||||
|
*/
|
||||||
|
void received(ShutdownMessage shutdownMessage);
|
||||||
|
|
||||||
|
void received(StartBriefingMessage msg);
|
||||||
|
|
||||||
|
void received(PlayerDataMessage msg);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,28 +8,13 @@
|
|||||||
*/
|
*/
|
||||||
@Serializable
|
@Serializable
|
||||||
public class ServerStartGameMessage extends ServerMessage {
|
public class ServerStartGameMessage extends ServerMessage {
|
||||||
/**
|
|
||||||
* Create ServerStartGameMessage attributes.
|
|
||||||
*/
|
|
||||||
private final Board board;
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new ServerStartGame instance.
|
* Constructs a new ServerStartGame instance.
|
||||||
*/
|
*/
|
||||||
public ServerStartGameMessage() {
|
public ServerStartGameMessage() {
|
||||||
super();
|
super();
|
||||||
this.board = null;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Constructor.
|
|
||||||
*
|
|
||||||
* @param board as the complete board of this game as a Board object.
|
|
||||||
*/
|
|
||||||
public ServerStartGameMessage(Board board) {
|
|
||||||
this.board = board;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Accepts a visitor to process this message.
|
* Accepts a visitor to process this message.
|
||||||
*
|
*
|
||||||
@@ -40,15 +25,6 @@ public void accept(ServerInterpreter interpreter) {
|
|||||||
interpreter.received(this);
|
interpreter.received(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* This method will be used to return board attribute of ServerStartGameMessage class.
|
|
||||||
*
|
|
||||||
* @return board as a Board object.
|
|
||||||
*/
|
|
||||||
public Board getBoard() {
|
|
||||||
return this.board;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Returns a string representation of this message.
|
* Returns a string representation of this message.
|
||||||
*
|
*
|
||||||
|
|||||||
@@ -0,0 +1,30 @@
|
|||||||
|
package pp.mdga.message.server;
|
||||||
|
|
||||||
|
import com.jme3.network.serializing.Serializable;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A message sent by the server to inform the clients that the server is shutting down.
|
||||||
|
*/
|
||||||
|
@Serializable
|
||||||
|
public class ShutdownMessage extends ServerMessage {
|
||||||
|
/**
|
||||||
|
* Accepts a visitor to process this message.
|
||||||
|
*
|
||||||
|
* @param interpreter the visitor to process this message
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public void accept(ServerInterpreter interpreter) {
|
||||||
|
interpreter.received(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Gets the bundle key of the informational text to be shown at the client.
|
||||||
|
* This key is used to retrieve the appropriate localized text for display.
|
||||||
|
*
|
||||||
|
* @return the bundle key of the informational text
|
||||||
|
*/
|
||||||
|
@Override
|
||||||
|
public String getInfoTextKey() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,33 @@
|
|||||||
|
package pp.mdga.message.server;
|
||||||
|
|
||||||
|
import com.jme3.network.serializing.Serializable;
|
||||||
|
import pp.mdga.game.Board;
|
||||||
|
|
||||||
|
@Serializable
|
||||||
|
public class StartBriefingMessage extends ServerMessage {
|
||||||
|
|
||||||
|
private final Board board;
|
||||||
|
|
||||||
|
public StartBriefingMessage(Board board) {
|
||||||
|
super();
|
||||||
|
this.board = board;
|
||||||
|
}
|
||||||
|
|
||||||
|
private StartBriefingMessage() {
|
||||||
|
this(null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public Board getBoard() {
|
||||||
|
return this.board;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void accept(ServerInterpreter interpreter) {
|
||||||
|
interpreter.received(this);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getInfoTextKey() {
|
||||||
|
return "";
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -18,23 +18,26 @@ public class UpdateTSKMessage extends ServerMessage {
|
|||||||
*/
|
*/
|
||||||
private final Color color;
|
private final Color color;
|
||||||
|
|
||||||
|
private final boolean isTaken;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructs a new UpdateTSK instance with the specified id and color.
|
* Constructs a new UpdateTSK instance with the specified id and color.
|
||||||
*
|
*
|
||||||
* @param id the name associated with the update
|
* @param id the name associated with the update
|
||||||
* @param color the color associated with the update
|
* @param color the color associated with the update
|
||||||
*/
|
*/
|
||||||
public UpdateTSKMessage(int id, Color color) {
|
public UpdateTSKMessage(int id, Color color, boolean isTaken) {
|
||||||
super();
|
super();
|
||||||
this.id = id;
|
this.id = id;
|
||||||
this.color = color;
|
this.color = color;
|
||||||
|
this.isTaken = isTaken;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Default constructor for serialization purposes.
|
* Default constructor for serialization purposes.
|
||||||
*/
|
*/
|
||||||
private UpdateTSKMessage() {
|
private UpdateTSKMessage() {
|
||||||
this(0, null);
|
this(0, null, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -84,4 +87,8 @@ public String toString() {
|
|||||||
public String getInfoTextKey() {
|
public String getInfoTextKey() {
|
||||||
return "";
|
return "";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isTaken() {
|
||||||
|
return isTaken;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -11,6 +11,7 @@ public class RollDiceNotification extends Notification{
|
|||||||
private int eyes;
|
private int eyes;
|
||||||
private boolean turbo;
|
private boolean turbo;
|
||||||
private int multiplier;
|
private int multiplier;
|
||||||
|
private boolean isRanking;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Constructor.
|
* Constructor.
|
||||||
@@ -22,6 +23,15 @@ public RollDiceNotification(Color color, int eyes) {
|
|||||||
this.eyes = eyes;
|
this.eyes = eyes;
|
||||||
this.turbo = false;
|
this.turbo = false;
|
||||||
this.multiplier = -1;
|
this.multiplier = -1;
|
||||||
|
this.isRanking = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
public RollDiceNotification(Color color, int eyes, boolean isRanking) {
|
||||||
|
this.color = color;
|
||||||
|
this.eyes = eyes;
|
||||||
|
this.turbo = false;
|
||||||
|
this.multiplier = -1;
|
||||||
|
this.isRanking = isRanking;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier) {
|
public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier) {
|
||||||
@@ -29,6 +39,7 @@ public RollDiceNotification(Color color, int eyes, boolean turbo, int multiplier
|
|||||||
this.eyes = eyes;
|
this.eyes = eyes;
|
||||||
this.turbo = turbo;
|
this.turbo = turbo;
|
||||||
this.multiplier = multiplier;
|
this.multiplier = multiplier;
|
||||||
|
this.isRanking = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -54,4 +65,6 @@ public int getMultiplier() {
|
|||||||
public boolean isTurbo() {
|
public boolean isTurbo() {
|
||||||
return turbo;
|
return turbo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isRanking() { return isRanking; }
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -7,6 +7,7 @@
|
|||||||
import pp.mdga.message.server.*;
|
import pp.mdga.message.server.*;
|
||||||
import pp.mdga.server.ServerGameLogic;
|
import pp.mdga.server.ServerGameLogic;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -48,7 +49,7 @@ public void exit() {
|
|||||||
* This method will be used to initialize the game and all necessary objects.
|
* This method will be used to initialize the game and all necessary objects.
|
||||||
*/
|
*/
|
||||||
public void initializeGame() {
|
public void initializeGame() {
|
||||||
for (Map.Entry<Integer, Player> entry: this.logic.getGame().getPlayers().entrySet()) {
|
for (Map.Entry<Integer, Player> entry : this.logic.getGame().getPlayers().entrySet()) {
|
||||||
this.logic.getGame().getBoard().addPlayerData(entry.getValue().getColor(), new PlayerData(entry.getValue().getColor()));
|
this.logic.getGame().getBoard().addPlayerData(entry.getValue().getColor(), new PlayerData(entry.getValue().getColor()));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -63,7 +64,7 @@ public void initializeGame() {
|
|||||||
@Override
|
@Override
|
||||||
public void received(JoinedLobbyMessage msg, int from) {
|
public void received(JoinedLobbyMessage msg, int from) {
|
||||||
Player player = new Player(msg.getName());
|
Player player = new Player(msg.getName());
|
||||||
player.setColor(Color.getColorByIndex(this.logic.getGame().getPlayers().size()));
|
player.setColor(Color.NONE);
|
||||||
this.logic.getGame().addPlayer(from, player);
|
this.logic.getGame().addPlayer(from, player);
|
||||||
for (Map.Entry<Integer, Player> entry : this.logic.getGame().getPlayers().entrySet()) {
|
for (Map.Entry<Integer, Player> entry : this.logic.getGame().getPlayers().entrySet()) {
|
||||||
this.logic.getServerSender().broadcast(new LobbyPlayerJoinedMessage(entry.getKey(), entry.getValue(), entry.getKey() == this.logic.getGame().getHost()));
|
this.logic.getServerSender().broadcast(new LobbyPlayerJoinedMessage(entry.getKey(), entry.getValue(), entry.getKey() == this.logic.getGame().getHost()));
|
||||||
@@ -84,8 +85,13 @@ public void received(SelectTSKMessage msg, int from) {
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.logic.getGame().getPlayerById(from).getColor() != Color.NONE) {
|
||||||
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, this.logic.getGame().getPlayerById(from).getColor(), false));
|
||||||
|
}
|
||||||
|
|
||||||
this.logic.getGame().getPlayerById(from).setColor(msg.getColor());
|
this.logic.getGame().getPlayerById(from).setColor(msg.getColor());
|
||||||
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor()));
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, msg.getColor(), true));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -98,7 +104,7 @@ public void received(SelectTSKMessage msg, int from) {
|
|||||||
@Override
|
@Override
|
||||||
public void received(DeselectTSKMessage msg, int from) {
|
public void received(DeselectTSKMessage msg, int from) {
|
||||||
this.logic.getGame().getPlayerById(from).setColor(Color.NONE);
|
this.logic.getGame().getPlayerById(from).setColor(Color.NONE);
|
||||||
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE));
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, Color.NONE, false));
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -110,6 +116,28 @@ public void received(DeselectTSKMessage msg, int from) {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void received(LobbyReadyMessage msg, int from) {
|
public void received(LobbyReadyMessage msg, int from) {
|
||||||
|
//assign a free color
|
||||||
|
if (this.logic.getGame().getPlayerById(from).getColor() == Color.NONE) {
|
||||||
|
ArrayList<Color> colors = new ArrayList<>();
|
||||||
|
colors.add(Color.ARMY);
|
||||||
|
colors.add(Color.AIRFORCE);
|
||||||
|
colors.add(Color.NAVY);
|
||||||
|
colors.add(Color.CYBER);
|
||||||
|
|
||||||
|
for (Map.Entry<Integer, Player> entry : this.logic.getGame().getPlayers().entrySet()) {
|
||||||
|
if (colors.contains(entry.getValue().getColor())) {
|
||||||
|
colors.remove(entry.getValue().getColor());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (colors.size() < 1) {
|
||||||
|
throw new RuntimeException("can not assign a color");
|
||||||
|
}
|
||||||
|
|
||||||
|
this.logic.getGame().getPlayerById(from).setColor(colors.get(0));
|
||||||
|
this.logic.getServerSender().broadcast(new UpdateTSKMessage(from, colors.get(0), true));
|
||||||
|
}
|
||||||
|
|
||||||
this.logic.getGame().getPlayerById(from).setReady(true);
|
this.logic.getGame().getPlayerById(from).setReady(true);
|
||||||
this.logic.getServerSender().broadcast(new UpdateReadyMessage(from, true));
|
this.logic.getServerSender().broadcast(new UpdateReadyMessage(from, true));
|
||||||
for (Map.Entry<Integer, Player> entry : this.logic.getGame().getPlayers().entrySet()) {
|
for (Map.Entry<Integer, Player> entry : this.logic.getGame().getPlayers().entrySet()) {
|
||||||
@@ -120,8 +148,12 @@ public void received(LobbyReadyMessage msg, int from) {
|
|||||||
|
|
||||||
this.logic.getGame().setAllReady(true);
|
this.logic.getGame().setAllReady(true);
|
||||||
if (this.logic.getGame().allReady()) {
|
if (this.logic.getGame().allReady()) {
|
||||||
|
this.logic.getServerSender().broadcast(new StartBriefingMessage(this.logic.getGame().getBoard()));
|
||||||
this.initializeGame();
|
this.initializeGame();
|
||||||
this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard()));
|
for (Map.Entry<Color, PlayerData> entry : logic.getGame().getBoard().getPlayerData().entrySet()) {
|
||||||
|
this.logic.getServerSender().broadcast(new PlayerDataMessage(entry.getValue(), entry.getKey()));
|
||||||
|
}
|
||||||
|
this.logic.getServerSender().broadcast(new ServerStartGameMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -148,6 +180,9 @@ public void received(LobbyNotReadyMessage msg, int from) {
|
|||||||
*/
|
*/
|
||||||
@Override
|
@Override
|
||||||
public void received(LeaveGameMessage msg, int from) {
|
public void received(LeaveGameMessage msg, int from) {
|
||||||
|
if (from == this.logic.getGame().getHost()) {
|
||||||
|
this.logic.getServerSender().broadcast(new ShutdownMessage());
|
||||||
|
}
|
||||||
this.logic.getGame().removePlayer(from);
|
this.logic.getGame().removePlayer(from);
|
||||||
this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from));
|
this.logic.getServerSender().broadcast(new LobbyPlayerLeaveMessage(from));
|
||||||
this.logic.getServerSender().disconnectClient(from);
|
this.logic.getServerSender().disconnectClient(from);
|
||||||
@@ -164,7 +199,7 @@ public void received(LeaveGameMessage msg, int from) {
|
|||||||
public void received(StartGameMessage msg, int from) {
|
public void received(StartGameMessage msg, int from) {
|
||||||
if (msg.isForceStartGame() || this.logic.getGame().allReady()) {
|
if (msg.isForceStartGame() || this.logic.getGame().allReady()) {
|
||||||
this.initializeGame();
|
this.initializeGame();
|
||||||
this.logic.getServerSender().broadcast(new ServerStartGameMessage(this.logic.getGame().getBoard()));
|
this.logic.getServerSender().broadcast(new ServerStartGameMessage());
|
||||||
this.logic.setCurrentState(this.logic.getGameState());
|
this.logic.setCurrentState(this.logic.getGameState());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
import pp.mdga.message.client.RequestDieMessage;
|
import pp.mdga.message.client.RequestDieMessage;
|
||||||
import pp.mdga.message.server.ActivePlayerMessage;
|
import pp.mdga.message.server.ActivePlayerMessage;
|
||||||
import pp.mdga.message.server.DieMessage;
|
import pp.mdga.message.server.DieMessage;
|
||||||
|
import pp.mdga.message.server.EndOfTurnMessage;
|
||||||
import pp.mdga.server.ServerGameLogic;
|
import pp.mdga.server.ServerGameLogic;
|
||||||
import pp.mdga.server.automaton.GameState;
|
import pp.mdga.server.automaton.GameState;
|
||||||
|
|
||||||
@@ -69,6 +70,7 @@ public void received(RequestDieMessage msg, int from) {
|
|||||||
maximumRoll = entry.getValue();
|
maximumRoll = entry.getValue();
|
||||||
} else {
|
} else {
|
||||||
this.playersHaveToRoll.remove(entry.getKey());
|
this.playersHaveToRoll.remove(entry.getKey());
|
||||||
|
this.logic.getServerSender().send(entry.getKey(), new EndOfTurnMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user