merge development into test #26

Merged
j23f0712 merged 95 commits from development into dev/test 2024-12-01 21:02:48 +01:00
18 changed files with 49202 additions and 98 deletions
Showing only changes of commit 0b9fc90274 - Show all commits

View File

@@ -1,7 +1,7 @@
package pp.mdga.client; package pp.mdga.client;
public enum Asset { public enum Asset {
bigTent(0.8f), bigTent,
cardStack, cardStack,
cir, cir,
heer, heer,
@@ -29,7 +29,8 @@ public enum Asset {
tree_big("Models/tree_big/tree_big.obj", "Models/tree_big/tree_big_diff.png"), tree_big("Models/tree_big/tree_big.obj", "Models/tree_big/tree_big_diff.png"),
turboCard, turboCard,
swapCard, swapCard,
shieldCard shieldCard,
dice("Models/dice/dice.obj", "Models/dice/dice_diff.jpeg")
; ;
private final String modelPath; private final String modelPath;

View File

@@ -79,7 +79,7 @@ public void onAction(String name, boolean isPressed, float tpf) {
if(cardLayerSelect == null && boardSelect != null) { if(cardLayerSelect == null && boardSelect != null) {
//boardSelect //boardSelect
if(boardSelect instanceof PieceControl pieceControl){ if(boardSelect instanceof PieceControl pieceControl){
pieceControl.setSelect(); if(pieceControl.isSelectable()) gameView.getBoardHandler().pieceSelect(pieceControl);
} }
if(boardSelect instanceof NodeControl nodeControl){ if(boardSelect instanceof NodeControl nodeControl){
// nodeControl.outline(); // nodeControl.outline();

View File

@@ -8,7 +8,7 @@
import com.jme3.system.AppSettings; import com.jme3.system.AppSettings;
import pp.mdga.client.view.*; import pp.mdga.client.view.*;
import pp.mdga.game.Color; import pp.mdga.game.Color;
import pp.mdga.notification.PlayerInGameNotification; import pp.mdga.notification.*;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.List; import java.util.List;
@@ -70,9 +70,24 @@ public void simpleInitApp() {
test.add(UUID.randomUUID()); test.add(UUID.randomUUID());
test.add(UUID.randomUUID()); test.add(UUID.randomUUID());
List<UUID> test_1 = new ArrayList<>();
UUID player0_1 = UUID.randomUUID();
test_1.add(player0_1);
UUID player1_1 = UUID.randomUUID();
test_1.add(player1_1);
test_1.add(UUID.randomUUID());
test_1.add(UUID.randomUUID());
notificationSynchronizer.addTestNotification(new PlayerInGameNotification(Color.AIRFORCE, test, "Player 1")); notificationSynchronizer.addTestNotification(new PlayerInGameNotification(Color.AIRFORCE, test, "Player 1"));
notificationSynchronizer.addTestNotification(new PlayerInGameNotification(Color.NAVY, test_1, "Player 2"));
notificationSynchronizer.addTestNotification(new MovePieceNotification(player0, 0, true));
notificationSynchronizer.addTestNotification(new MovePieceNotification(player0_1, 20, true));
notificationSynchronizer.addTestNotification(new MovePieceNotification(player0_1, 20, 21));
notificationSynchronizer.addTestNotification(new MovePieceNotification(player1, 0, true));
notificationSynchronizer.addTestNotification(new MovePieceNotification(player0, 0, 7));
// notificationSynchronizer.addTestNotification(new SelectableMoveNotification(new ArrayList<>(List.of(player0, player1)), new ArrayList<>(List.of(7,3)), new ArrayList<>(List.of(false, false))));
notificationSynchronizer.addTestNotification(new SwapPieceNotification(player0, player0_1));
// notificationSynchronizer.addTestNotification(new SelectableSwapNotification(new ArrayList<>(List.of(player0, player1)), new ArrayList<>(List.of(player0_1))));
} }
@Override @Override

View File

@@ -71,8 +71,8 @@ private void handleGame(Notification notification) {
if (notification instanceof AcquireCardNotification) { if (notification instanceof AcquireCardNotification) {
// Handle AcquireCardNotification // Handle AcquireCardNotification
} else if (notification instanceof ActivePlayerNotification) { } else if (notification instanceof ActivePlayerNotification n) {
// Handle ActivePlayerNotification gameView.getGuiHandler().setActivePlayer(n.getColor());
} else if (notification instanceof CeremonyNotification) { } else if (notification instanceof CeremonyNotification) {
app.enter(MdgaState.CEREMONY); app.enter(MdgaState.CEREMONY);
} else if (notification instanceof DiceNowNotification) { } else if (notification instanceof DiceNowNotification) {
@@ -85,9 +85,15 @@ private void handleGame(Notification notification) {
gameView.getBoardHandler().moveHomePiece(home.getPieceId(), home.getHomeIndex()); gameView.getBoardHandler().moveHomePiece(home.getPieceId(), home.getHomeIndex());
} else if (notification instanceof InterruptNotification) { } else if (notification instanceof InterruptNotification) {
// Handle InterruptNotification // Handle InterruptNotification
} else if (notification instanceof MovePieceNotification) { } else if (notification instanceof MovePieceNotification n) {
MovePieceNotification n = (MovePieceNotification)notification; if(n.isMoveStart()) {
//gameView.getBoardHandler().movePiece(n.get); //TODO //StartMove
gameView.getBoardHandler().movePieceStart(n.getPiece(), n.getMoveIndex());
}
else {
//InfieldMove
gameView.getBoardHandler().movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
}
} else if (notification instanceof MoveThrowPieceNotification) { } else if (notification instanceof MoveThrowPieceNotification) {
MoveThrowPieceNotification n = (MoveThrowPieceNotification)notification; MoveThrowPieceNotification n = (MoveThrowPieceNotification)notification;
//gameView.getBoardHandler().throwPiece(n.); //TODO //gameView.getBoardHandler().throwPiece(n.); //TODO
@@ -102,16 +108,12 @@ private void handleGame(Notification notification) {
// Handle PlayerInGameNotification // Handle PlayerInGameNotification
gameView.getBoardHandler().addPlayer(n.getColor(),n.getPiecesList()); gameView.getBoardHandler().addPlayer(n.getColor(),n.getPiecesList());
gameView.getGuiHandler().addPlayer(n.getColor(),n.getName()); gameView.getGuiHandler().addPlayer(n.getColor(),n.getName());
gameView.getBoardHandler().enableHover(n.getPiecesList().get(0));
gameView.getBoardHandler().highlight(n.getPiecesList().get(0), true);
} else if (notification instanceof ResumeNotification) { } else if (notification instanceof ResumeNotification) {
// Handle ResumeNotification // Handle ResumeNotification
} else if (notification instanceof RollDiceNotification) { } else if (notification instanceof RollDiceNotification) {
// Handle RollDiceNotification // Handle RollDiceNotification
} else if (notification instanceof SelectableCardsNotification) { } else if (notification instanceof SelectableCardsNotification) {
// Handle SelectableCardsNotification // Handle SelectableCardsNotification
} else if (notification instanceof SelectablePiecesNotification) {
// Handle SelectablePiecesNotification
} else if (notification instanceof ShieldActiveNotification) { } else if (notification instanceof ShieldActiveNotification) {
ShieldActiveNotification n = (ShieldActiveNotification)notification; ShieldActiveNotification n = (ShieldActiveNotification)notification;
gameView.getBoardHandler().shieldPiece(n.getPieceId()); gameView.getBoardHandler().shieldPiece(n.getPieceId());
@@ -120,10 +122,14 @@ private void handleGame(Notification notification) {
gameView.getBoardHandler().suppressShield(n.getPieceId()); gameView.getBoardHandler().suppressShield(n.getPieceId());
} else if (notification instanceof StartDialogNotification) { } else if (notification instanceof StartDialogNotification) {
app.enter(MdgaState.MAIN); app.enter(MdgaState.MAIN);
} else if (notification instanceof SwapPieceNotification) { } else if (notification instanceof SwapPieceNotification n) {
// Handle SwapPieceNotification gameView.getBoardHandler().swapPieces(n.getFirstPiece(), n.getSecondPiece());
} else if (notification instanceof WaitMoveNotification) { } else if (notification instanceof WaitMoveNotification) {
// Handle WaitMoveNotification // Handle WaitMoveNotification
} else if (notification instanceof SelectableMoveNotification n) {
gameView.getBoardHandler().outlineMove(n.getPieces(), n.getMoveIndexe(), n.getHomeMoves());
} else if (notification instanceof SelectableSwapNotification n) {
gameView.getBoardHandler().outlineSwap(n.getOwnPieces(), n.getEnemyPieces());
} else { } else {
throw new RuntimeException("notification not expected: " + notification.toString()); throw new RuntimeException("notification not expected: " + notification.toString());
} }

View File

@@ -42,13 +42,19 @@ public class BoardHandler {
private boolean scheduleInit = false; private boolean scheduleInit = false;
private boolean scheduleShutdown = false; private boolean scheduleShutdown = false;
private List<PieceControl> selectableOwnPieces = new ArrayList<>();
private List<PieceControl> selectableEnemyPieces = new ArrayList<>();
private PieceControl selectedOwnPiece;
private PieceControl selectedEnemyPiece;
public BoardHandler(MdgaApp app, FilterPostProcessor fpp) { public BoardHandler(MdgaApp app, FilterPostProcessor fpp) {
if(app == null) throw new RuntimeException("app is null"); if(app == null) throw new RuntimeException("app is null");
this.isInitialised = false; this.isInitialised = false;
this.app = app; this.app = app;
this.fpp = fpp; this.fpp = fpp;
selectedEnemyPiece = null;
selectedOwnPiece = null;
initMap(); initMap();
} }
@@ -153,7 +159,9 @@ private void addHomeNode(Map<Color, List<NodeControl>> map, Color color, AssetOn
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.
return (float) Math.toDegrees(Math.atan2(direction.x, -direction.y)); float newRot = (float) Math.toDegrees(Math.atan2(direction.x, -direction.y));
if(newRot < 0) newRot += 360;
return newRot;
} }
private void movePiece_rek(UUID uuid, int curIndex, int moveIndex){ private void movePiece_rek(UUID uuid, int curIndex, int moveIndex){
@@ -200,6 +208,7 @@ 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);
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());
movePieceToNode(pieceControl, waitNodes.get(i)); movePieceToNode(pieceControl, waitNodes.get(i));
pieces.put(uuid.get(i), pieceControl); pieces.put(uuid.get(i), pieceControl);
@@ -343,11 +352,117 @@ public void deOutline(UUID uuid){
} }
public void outline(int index){ public void outline(int index){
infield.get(index).outline(); // infield.get(index).outline();
outlineControls.add(infield.get(index)); outlineControls.add(infield.get(index));
} }
//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) {
if(pieces.size() != moveIndexe.size() || pieces.size() != homeMoves.size()) throw new RuntimeException("arrays are not the same size");
selectableEnemyPieces.clear();
selectableOwnPieces.clear();
selectedOwnPiece = null;
selectedEnemyPiece = null;
for (int i = 0; i < pieces.size(); i++) {
UUID uuid = pieces.get(i);
PieceControl pieceControl = this.pieces.get(uuid);
NodeControl nodeControl;
if (homeMoves.get(i)) {
Color color = pieceColor.get(uuid);
nodeControl = homeNodesMap.get(color).get(moveIndexe.get(i));
}
else {
nodeControl = infield.get(moveIndexe.get(i));
}
nodeControl.highlight();
pieceControl.highlight(false);
pieceControl.setHoverable(true);
pieceControl.setSelectable(true);
selectableOwnPieces.add(pieceControl);
}
}
//called when swap notification is received to highlight and select own/enemy pieces
public void outlineSwap(List<UUID> ownPieces, List<UUID> enemyPieces){
selectableEnemyPieces.clear();
selectableOwnPieces.clear();
selectedOwnPiece = null;
selectedEnemyPiece = null;
for(UUID uuid : ownPieces) {
PieceControl p = pieces.get(uuid);
p.highlight(false);
p.setHoverable(true);
p.setSelectable(true);
selectableOwnPieces.add(p);
}
for(UUID uuid : enemyPieces) {
PieceControl p = pieces.get(uuid);
p.highlight(true);
p.setHoverable(true);
p.setSelectable(true);
selectableEnemyPieces.add(p);
}
}
//called from inputSynchronizer when a piece is selectable
public void pieceSelect(PieceControl pieceSelected) {
boolean isSelected = pieceSelected.isSelected();
if(selectableOwnPieces.contains(pieceSelected)){
for(PieceControl p : selectableOwnPieces) {
p.unSelect();
}
if (!isSelected) {
pieceSelected.select();
selectedOwnPiece = pieceSelected;
}
else {
pieceSelected.unSelect();
selectedOwnPiece = null;
}
}
else if(selectableEnemyPieces.contains(pieceSelected)) {
for(PieceControl p : selectableEnemyPieces) {
p.unSelect();
}
if (!isSelected) {
pieceSelected.select();
selectedEnemyPiece = pieceSelected;
}
else {
pieceSelected.unSelect();
selectedEnemyPiece = null;
}
}
else throw new RuntimeException("pieceSelected is not in own/enemySelectablePieces");
}
//called when view is no longer needed to select pieces
public void clearSelectable(){
for(PieceControl p : selectableEnemyPieces) {
p.unSelect();
p.setSelectable(false);
}
for(PieceControl p : selectableOwnPieces) {
p.unSelect();
p.setSelectable(false);
}
selectableEnemyPieces.clear();
selectableOwnPieces.clear();
selectedEnemyPiece = null;
selectedOwnPiece = null;
}
public void deOutline(int index){ public void deOutline(int index){
infield.get(index).deOutline(); infield.get(index).deOutline();

View File

@@ -10,17 +10,18 @@
public class NodeControl extends OutlineControl { public class NodeControl extends OutlineControl {
private static final ColorRGBA OUTLINE_COLOR = ColorRGBA.White; private static final ColorRGBA OUTLINE_HIGHLIGHT_COLOR = ColorRGBA.White;
private static final int OUTLINE_HIGHLIGHT_WIDTH = 6;
public NodeControl(MdgaApp app, FilterPostProcessor fpp) { public NodeControl(MdgaApp app, FilterPostProcessor fpp) {
super(app, fpp); super(app, fpp);
} }
public void outline(){
super.outline(OUTLINE_COLOR);
}
public Vector3f getLocation(){ public Vector3f getLocation(){
return this.getSpatial().getLocalTranslation(); return this.getSpatial().getLocalTranslation();
} }
public void highlight() {
super.outline(OUTLINE_HIGHLIGHT_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
}
} }

View File

@@ -30,7 +30,8 @@ public class PieceControl extends OutlineControl {
private static final ColorRGBA OUTLINE_ENEMY_COLOR = ColorRGBA.Red; private static final ColorRGBA OUTLINE_ENEMY_COLOR = ColorRGBA.Red;
private static final ColorRGBA OUTLINE_OWN_HOVER_COLOR = ColorRGBA.Yellow; private static final ColorRGBA OUTLINE_OWN_HOVER_COLOR = ColorRGBA.Yellow;
private static final ColorRGBA OUTLINE_ENEMY_HOVER_COLOR = ColorRGBA.Green; private static final ColorRGBA OUTLINE_ENEMY_HOVER_COLOR = ColorRGBA.Green;
private static final ColorRGBA OUTLINE_SELECT_COLOR = ColorRGBA.Blue; private static final ColorRGBA OUTLINE_OWN_SELECT_COLOR = ColorRGBA.Cyan;
private static final ColorRGBA OUTLINE_ENEMY_SELECT_COLOR = ColorRGBA.Orange;
private static final int OUTLINE_HIGHLIGHT_WIDTH = 6; private static final int OUTLINE_HIGHLIGHT_WIDTH = 6;
private static final int OUTLINE_HOVER_WIDTH = 6; private static final int OUTLINE_HOVER_WIDTH = 6;
private static final int OUTLINE_SELECT_WIDTH = 8; private static final int OUTLINE_SELECT_WIDTH = 8;
@@ -59,17 +60,19 @@ public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app,
} }
public float getRotation() { public float getRotation() {
return (float) Math.toDegrees(this.spatial.getLocalRotation().toAngleAxis(new Vector3f(0,0,1))); return (float) Math.toDegrees(spatial.getLocalRotation().toAngleAxis(new Vector3f(0,0,1)));
} }
public void setRotation(float rot){ public void setRotation(float rot){
if(rot < 0) rot =- 360;
Quaternion quaternion = new Quaternion(); Quaternion quaternion = new Quaternion();
quaternion.fromAngleAxis((float) Math.toRadians(rot), new Vector3f(0,0,1)); quaternion.fromAngleAxis((float) Math.toRadians(rot), new Vector3f(0,0,1));
this.spatial.setLocalRotation(quaternion); spatial.setLocalRotation(quaternion);
} }
public Vector3f getLocation(){ public Vector3f getLocation(){
return this.getSpatial().getLocalTranslation(); return spatial.getLocalTranslation();
} }
@Override @Override
@@ -80,12 +83,12 @@ protected void controlUpdate(float delta) {
} }
public void setLocation(Vector3f loc){ public void setLocation(Vector3f loc){
this.getSpatial().setLocalTranslation(loc); this.spatial.setLocalTranslation(loc);
} }
@Override @Override
public void setSpatial(Spatial spatial){ public void setSpatial(Spatial spatial){
if(this.getSpatial() == null && spatial != null){ if(this.spatial == null && spatial != null){
super.setSpatial(spatial); super.setSpatial(spatial);
initSpatial(); initSpatial();
} }
@@ -97,8 +100,8 @@ public void setSpatial(Spatial spatial){
public void initSpatial(){ public void initSpatial(){
setRotation(this.initRotation); setRotation(this.initRotation);
Node oldParent = this.spatial.getParent(); Node oldParent = spatial.getParent();
this.parentNode.setName(this.spatial.getName() + " Parent"); this.parentNode.setName(spatial.getName() + " Parent");
oldParent.detachChild(this.getSpatial()); oldParent.detachChild(this.getSpatial());
this.parentNode.attachChild(this.getSpatial()); this.parentNode.attachChild(this.getSpatial());
oldParent.attachChild(this.parentNode); oldParent.attachChild(this.parentNode);
@@ -133,11 +136,11 @@ public void suppressShield(){
} }
public void setMaterial(Material mat){ public void setMaterial(Material mat){
this.spatial.setMaterial(mat); spatial.setMaterial(mat);
} }
public Material getMaterial(){ public Material getMaterial(){
return ((Geometry) this.spatial).getMaterial(); return ((Geometry) getSpatial()).getMaterial();
} }
@@ -166,20 +169,27 @@ public void hoverOff(){
else deOutline(); else deOutline();
} }
public void select(){ public void unSelect(){
super.outline(OUTLINE_SELECT_COLOR, OUTLINE_SELECT_WIDTH); select = false;
if(highlight) highlight(enemy);
else deOutline();
} }
public void setSelect(){ public void select(){
if(!selectable) return; if(!selectable) return;
select = !select; select = true;
if(select) select(); super.outline(enemy ? OUTLINE_ENEMY_SELECT_COLOR : OUTLINE_OWN_SELECT_COLOR, OUTLINE_SELECT_WIDTH);
} }
public void setSelectable(boolean selectable){ public void setSelectable(boolean selectable){
this.selectable = selectable; this.selectable = selectable;
} }
public boolean isSelected() { return select; }
public boolean isSelectable() {
return selectable;
}
public void setHoverable(boolean hoverable) { public void setHoverable(boolean hoverable) {
this.hoverable = hoverable; this.hoverable = hoverable;

View File

@@ -44,7 +44,7 @@ public void initialize(AppStateManager stateManager, Application app ) {
ViewPort view = app.getRenderManager().createMainView("Under gui ViewPort", overlayCam); ViewPort view = app.getRenderManager().createMainView("Under gui ViewPort", overlayCam);
view.setEnabled(true); view.setEnabled(true);
view.setClearFlags(false, true, false); view.setClearFlags(true, true, true);
view.attachScene(root); view.attachScene(root);
fpp.setFrameBufferFormat(Image.Format.RGBA8); fpp.setFrameBufferFormat(Image.Format.RGBA8);
fpp.addFilter(new ComposeFilter(backTexture)); fpp.addFilter(new ComposeFilter(backTexture));
@@ -67,7 +67,7 @@ public void render(RenderManager rm) {
@Override @Override
public void update( float tpf ) { public void update( float tpf ) {
root.updateLogicalState(tpf);
if (init && !cardBuffer.isEmpty()) { if (init && !cardBuffer.isEmpty()) {
for(Spatial spatial : cardBuffer){ for(Spatial spatial : cardBuffer){
@@ -75,13 +75,14 @@ public void update( float tpf ) {
} }
cardBuffer.clear(); cardBuffer.clear();
} }
root.updateLogicalState(tpf);
} }
public void addCard(Spatial card){ public void addSpatial(Spatial card){
cardBuffer.add(card); cardBuffer.add(card);
} }
public void deleteCard(Spatial spatial){ public void deleteSpatial(Spatial spatial){
root.detachChild(spatial); root.detachChild(spatial);
} }

View File

@@ -0,0 +1,105 @@
package pp.mdga.client.gui;
import com.jme3.math.Quaternion;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.scene.control.AbstractControl;
import java.util.Random;
public class DiceControl extends AbstractControl {
private final Random random = new Random();
private Quaternion targetRotation; // Final rotation of the dice
private final Vector3f angularVelocity = new Vector3f(); // Rotational velocity (radians/sec)
private float deceleration = 0.5f; // Friction-like deceleration
private boolean isRolling = false;
private boolean slerp = false;
private float timeElapsed = 0.0f;
private float rollDuration = 0.0001f;
@Override
protected void controlUpdate(float tpf) {
if (isRolling) {
if(!slerp) {
// Apply rotational velocity to the dice
Quaternion currentRotation = spatial.getLocalRotation();
Quaternion deltaRotation = new Quaternion();
deltaRotation.fromAngles(
angularVelocity.x * tpf,
angularVelocity.y * tpf,
angularVelocity.z * tpf
);
spatial.setLocalRotation(currentRotation.mult(deltaRotation));
// Gradually reduce rotational velocity (simulate deceleration)
angularVelocity.subtractLocal(
angularVelocity.mult(deceleration * tpf)
);
// Stop rolling when angular velocity is close to zero
if (angularVelocity.lengthSquared() < 3f) {
slerp = true;
}
}
else {
timeElapsed += tpf * rollDuration;
if (timeElapsed > 1.0f) timeElapsed = 1.0f;
// Quaternion interpolated = new Quaternion();
// interpolated.slerp(spatial.getLocalRotation(), targetRotation, progress);
// spatial.setLocalRotation(interpolated);
Quaternion interpolated = spatial.getLocalRotation().clone();
interpolated.nlerp(targetRotation, lerp(timeElapsed));
spatial.setLocalRotation(interpolated);
// Stop rolling once duration is complete
if (timeElapsed >= 1.0f) {
isRolling = false;
slerp = false;
}
}
}
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
// No custom rendering needed
}
public void rollDice(int diceNum) {
if (isRolling) return; // Prevent re-rolling during animation
// Set high initial rotational velocity
angularVelocity.set(
random.nextFloat() * 1000f + 200f, // X-axis speed
random.nextFloat() * 1000f + 200f, // Y-axis speed
random.nextFloat() * 1000f + 200f // Z-axis speed
);
// Set final target rotation for the diceNum
targetRotation = getRotationForDiceNum(diceNum);
isRolling = true;
}
private Quaternion getRotationForDiceNum(int diceNum) {
// Define specific rotations for each dice face (adjust based on your dice model)
return switch (diceNum) {
case 1 -> new Quaternion().fromAngleAxis((float) (1 * (Math.PI / 2)), Vector3f.UNIT_X); //
case 2 -> new Quaternion().fromAngleAxis((float) (1 * (Math.PI / 2)), Vector3f.UNIT_Y); //
case 3 -> new Quaternion().fromAngleAxis((float) (0 * (Math.PI / 2)), Vector3f.UNIT_X); //
case 4 -> new Quaternion().fromAngleAxis((float) (2 * (Math.PI / 2)), Vector3f.UNIT_Y); //
case 5 -> new Quaternion().fromAngleAxis((float) (3 * (Math.PI / 2)), Vector3f.UNIT_Y); //
case 6 -> new Quaternion().fromAngleAxis((float) (3 * (Math.PI / 2)), Vector3f.UNIT_X); //
default -> throw new IllegalArgumentException("Invalid dice number: " + diceNum);
};
}
public static float lerp(float t) {
return (float) Math.sqrt(1 - Math.pow(t - 1, 2));
}
}

View File

@@ -75,13 +75,32 @@ private Asset bonusToAsset(BonusCard card){
public void addCard(BonusCard card, UUID uuid) { public void addCard(BonusCard card, UUID uuid) {
CardControl control = createCard(bonusToAsset(card), nextPos()); CardControl control = createCard(bonusToAsset(card), nextPos());
ownCardsMap.put(uuid, control); ownCardsMap.put(uuid, control);
cardLayer.addCard(control.getSpatial()); cardLayer.addSpatial(control.getSpatial());
}
public void showDice(){
DiceControl control = createDice();
cardLayer.addSpatial(control.getSpatial());
control.rollDice(1);
}
private DiceControl createDice() {
Spatial spatial = app.getAssetManager().loadModel(Asset.dice.getModelPath());
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Unshaded.j3md");
mat.setTexture("ColorMap", app.getAssetManager().loadTexture(Asset.dice.getDiffPath()));
spatial.setMaterial(mat);
spatial.setLocalScale(1f);
spatial.setLocalTranslation(new Vector3f(0,0,0));
spatial.rotate((float)Math.toRadians(90), (float)Math.toRadians(180), (float)Math.toRadians(180));
DiceControl control = new DiceControl();
spatial.addControl(control);
return control;
} }
public void deleteCard(UUID uuid){ public void deleteCard(UUID uuid){
if(!ownCardsMap.containsKey(uuid)) throw new RuntimeException("uuid dont exist in ownCardsmap"); if(!ownCardsMap.containsKey(uuid)) throw new RuntimeException("uuid dont exist in ownCardsmap");
cardLayer.deleteCard(ownCardsMap.get(uuid).getSpatial()); cardLayer.deleteSpatial(ownCardsMap.get(uuid).getSpatial());
ownCardsMap.remove(uuid); ownCardsMap.remove(uuid);
} }
@@ -129,8 +148,6 @@ private void renderName(String name, float paddingTop, float paddingLeft, boolea
playerNameNode.attachChild(hudText); playerNameNode.attachChild(hudText);
} }
public void setPlayers(List<String> names, List<Color> colors){ public void setPlayers(List<String> names, List<Color> colors){
if(names.size() != colors.size()) throw new RuntimeException("names and colors are not the same size"); if(names.size() != colors.size()) throw new RuntimeException("names and colors are not the same size");
@@ -175,7 +192,7 @@ public void test(){
addCard(BonusCard.TURBO, UUID.randomUUID()); addCard(BonusCard.TURBO, UUID.randomUUID());
addCard(BonusCard.SWAP, UUID.randomUUID()); addCard(BonusCard.SWAP, UUID.randomUUID());
// ownCardsMap.get(uuid).outline(); showDice();
} }
public Camera getCardLayerCamera() { public Camera getCardLayerCamera() {
@@ -185,4 +202,6 @@ public Camera getCardLayerCamera() {
public CardLayer getCardLayer(){ public CardLayer getCardLayer(){
return cardLayer; return cardLayer;
} }
} }

View File

@@ -4,10 +4,10 @@ world 0,0 90
#tree_big 0,0 0 #tree_big 0,0 0
#Marine Pos #Marine Pos
marine 4,-5 -90 marine 4,-5 270
marine 4,-4 -90 marine 4,-4 270
marine 5,-4 -90 marine 5,-4 270
marine 5,-5 -90 marine 5,-5 270
#Blue (Marine) wait Node #Blue (Marine) wait Node
node_wait_blue 4,-5 0 node_wait_blue 4,-5 0

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 2.8 MiB

View File

@@ -2,37 +2,76 @@
import pp.mdga.game.Color; import pp.mdga.game.Color;
import java.util.UUID;
/** /**
* Notification that a piece has been moved. * Notification that a piece has been moved.
*/ */
public class MovePieceNotification extends Notification { public class MovePieceNotification extends Notification {
private Color color; /**
private int nodeIndex; * The unique identifier of the piece being moved.
*/
private final UUID piece;
/** /**
* Constructor. * The index of the node from which the piece started moving.
* @param color the color of the piece that has been moved. * Ignored if {@code moveStart} is {@code true}.
* @param nodeIndex the index of the node the piece has been moved to.
*/ */
MovePieceNotification(Color color, int nodeIndex) { private final int startIndex;
this.color = color;
this.nodeIndex = nodeIndex; /**
* The index of the node to which the piece is moving.
* If {@code moveStart} is {@code true}, this index represents the start node.
*/
private final int moveIndex;
/**
* Flag indicating that the piece ({@code uuid}) is moving from waiting area to the startNode.
*/
private final boolean moveStart;
/**
* Constructs a notification for a piece start movement.
*
* @param piece the unique identifier of the piece
* @param moveIndex the destination node index
* @param moveStart whether to ignore {@code startIndex} and use {@code moveIndex} as the start node
*/
public MovePieceNotification(UUID piece, int moveIndex, boolean moveStart) {
this.piece = piece;
this.startIndex = 0;
this.moveIndex = moveIndex;
this.moveStart = moveStart;
} }
/** /**
* Get the color of the piece that has been moved. * Constructs a notification for a piece infield move with {@code moveStart} set to {@code false}.
* @return the color of the piece that has been moved. *
* @param piece the unique identifier of the piece
* @param startIndex the starting node index
* @param moveIndex the destination node index
*/ */
public Color getColor() { public MovePieceNotification(UUID piece, int startIndex, int moveIndex) {
return color; this.piece = piece;
this.startIndex = startIndex;
this.moveIndex = moveIndex;
this.moveStart = false;
} }
/** public int getMoveIndex() {
* Get the index of the node the piece has been moved to. return moveIndex;
* @return the index of the node the piece has been moved to. }
*/
public int getNodeIndex() { public int getStartIndex() {
return nodeIndex; return startIndex;
}
public UUID getPiece() {
return piece;
}
public boolean isMoveStart() {
return moveStart;
} }
} }

View File

@@ -0,0 +1,66 @@
package pp.mdga.notification;
import java.util.List;
import java.util.UUID;
/**
* Notification for selecting pieces and their possible moves.
*/
public class SelectableMoveNotification extends Notification{
/**
* List of UUIDs representing the pieces that can be moved based on the dice roll.
*/
private final List<UUID> pieces;
/**
* List of integers representing the target nodes the pieces can move to.
*/
private final List<Integer> moveIndexe;
/**
* List of booleans indicating whether the corresponding target nodes are in the home area.
* {@code true} if the target node is in the home area, {@code false} if in the infield.
*/
private final List<Boolean> homeMoves;
/**
* Constructs a notification for selectable piece moves.
*
* @param pieces the list of pieces that can be moved
* @param moveIndexe the list of target nodes for the moves
* @param homeMoves the list indicating if the target nodes are in the home area
*/
public SelectableMoveNotification(List<UUID> pieces, List<Integer> moveIndexe, List<Boolean> homeMoves) {
this.pieces = pieces;
this.moveIndexe = moveIndexe;
this.homeMoves = homeMoves;
}
/**
* Gets the list of pieces that can be moved.
*
* @return a list of UUIDs representing the movable pieces
*/
public List<UUID> getPieces() {
return pieces;
}
/**
* Gets the list of target nodes for the moves.
*
* @return a list of integers representing the target nodes
*/
public List<Integer> getMoveIndexe() {
return moveIndexe;
}
/**
* Gets the list indicating whether the target nodes are in the home area.
*
* @return a list of booleans, {@code true} if the target node is in the home area, {@code false} otherwise
*/
public List<Boolean> getHomeMoves() {
return homeMoves;
}
}

View File

@@ -1,26 +0,0 @@
package pp.mdga.notification;
import java.util.List;
import java.util.UUID;
/**
* Notification to inform the client about the selectable pieces.
*/
public class SelectablePiecesNotification extends Notification{
private List<UUID> selectablePieces;
/**
* @param selectablePieces
*/
SelectablePiecesNotification(List<UUID> selectablePieces){
this.selectablePieces = selectablePieces;
}
/**
* @return List<UUID>
*/
public List<UUID> getSelectablePieces(){
return selectablePieces;
}
}

View File

@@ -0,0 +1,49 @@
package pp.mdga.notification;
import java.util.List;
import java.util.UUID;
/**
* Notification for selecting pieces for swapcard.
*/
public class SelectableSwapNotification extends Notification{
/**
* List of UUIDs representing the player's own pieces available for selection.
*/
private final List<UUID> ownPieces;
/**
* List of UUIDs representing the opponent's pieces available for selection.
*/
private final List<UUID> enemyPieces;
/**
* Constructs a notification for selecting pieces for swapcard.
*
* @param ownPieces the list of the player's own pieces
* @param enemyPieces the list of the opponent's pieces
*/
public SelectableSwapNotification(List<UUID> ownPieces, List<UUID> enemyPieces) {
this.ownPieces = ownPieces;
this.enemyPieces = enemyPieces;
}
/**
* Gets the list of the player's own pieces available for selection.
*
* @return a list of UUIDs representing the player's own pieces
*/
public List<UUID> getOwnPieces() {
return ownPieces;
}
/**
* Gets the list of the opponent's pieces available for selection.
*
* @return a list of UUIDs representing the opponent's pieces
*/
public List<UUID> getEnemyPieces() {
return enemyPieces;
}
}

View File

@@ -15,7 +15,7 @@ public class SwapPieceNotification extends Notification {
* @param firstPiece the UUID of the first piece that has been swapped. * @param firstPiece the UUID of the first piece that has been swapped.
* @param secondPiece the UUID of the second piece that has been swapped. * @param secondPiece the UUID of the second piece that has been swapped.
*/ */
SwapPieceNotification(UUID firstPiece, UUID secondPiece) { public SwapPieceNotification(UUID firstPiece, UUID secondPiece) {
assert(!firstPiece.equals(secondPiece)); assert(!firstPiece.equals(secondPiece));
this.firstPiece = firstPiece; this.firstPiece = firstPiece;
this.secondPiece = secondPiece; this.secondPiece = secondPiece;