merge development into test #26
@@ -1,7 +1,7 @@
|
||||
package pp.mdga.client;
|
||||
|
||||
public enum Asset {
|
||||
bigTent(0.8f),
|
||||
bigTent,
|
||||
cardStack,
|
||||
cir,
|
||||
heer,
|
||||
@@ -29,7 +29,8 @@ public enum Asset {
|
||||
tree_big("Models/tree_big/tree_big.obj", "Models/tree_big/tree_big_diff.png"),
|
||||
turboCard,
|
||||
swapCard,
|
||||
shieldCard
|
||||
shieldCard,
|
||||
dice("Models/dice/dice.obj", "Models/dice/dice_diff.jpeg")
|
||||
;
|
||||
|
||||
private final String modelPath;
|
||||
|
||||
@@ -79,7 +79,7 @@ public void onAction(String name, boolean isPressed, float tpf) {
|
||||
if(cardLayerSelect == null && boardSelect != null) {
|
||||
//boardSelect
|
||||
if(boardSelect instanceof PieceControl pieceControl){
|
||||
pieceControl.setSelect();
|
||||
if(pieceControl.isSelectable()) gameView.getBoardHandler().pieceSelect(pieceControl);
|
||||
}
|
||||
if(boardSelect instanceof NodeControl nodeControl){
|
||||
// nodeControl.outline();
|
||||
|
||||
@@ -8,7 +8,7 @@
|
||||
import com.jme3.system.AppSettings;
|
||||
import pp.mdga.client.view.*;
|
||||
import pp.mdga.game.Color;
|
||||
import pp.mdga.notification.PlayerInGameNotification;
|
||||
import pp.mdga.notification.*;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.List;
|
||||
@@ -70,9 +70,24 @@ public void simpleInitApp() {
|
||||
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.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
|
||||
|
||||
@@ -71,8 +71,8 @@ private void handleGame(Notification notification) {
|
||||
|
||||
if (notification instanceof AcquireCardNotification) {
|
||||
// Handle AcquireCardNotification
|
||||
} else if (notification instanceof ActivePlayerNotification) {
|
||||
// Handle ActivePlayerNotification
|
||||
} else if (notification instanceof ActivePlayerNotification n) {
|
||||
gameView.getGuiHandler().setActivePlayer(n.getColor());
|
||||
} else if (notification instanceof CeremonyNotification) {
|
||||
app.enter(MdgaState.CEREMONY);
|
||||
} else if (notification instanceof DiceNowNotification) {
|
||||
@@ -85,9 +85,15 @@ private void handleGame(Notification notification) {
|
||||
gameView.getBoardHandler().moveHomePiece(home.getPieceId(), home.getHomeIndex());
|
||||
} else if (notification instanceof InterruptNotification) {
|
||||
// Handle InterruptNotification
|
||||
} else if (notification instanceof MovePieceNotification) {
|
||||
MovePieceNotification n = (MovePieceNotification)notification;
|
||||
//gameView.getBoardHandler().movePiece(n.get); //TODO
|
||||
} else if (notification instanceof MovePieceNotification n) {
|
||||
if(n.isMoveStart()) {
|
||||
//StartMove
|
||||
gameView.getBoardHandler().movePieceStart(n.getPiece(), n.getMoveIndex());
|
||||
}
|
||||
else {
|
||||
//InfieldMove
|
||||
gameView.getBoardHandler().movePiece(n.getPiece(), n.getStartIndex(), n.getMoveIndex());
|
||||
}
|
||||
} else if (notification instanceof MoveThrowPieceNotification) {
|
||||
MoveThrowPieceNotification n = (MoveThrowPieceNotification)notification;
|
||||
//gameView.getBoardHandler().throwPiece(n.); //TODO
|
||||
@@ -102,16 +108,12 @@ private void handleGame(Notification notification) {
|
||||
// Handle PlayerInGameNotification
|
||||
gameView.getBoardHandler().addPlayer(n.getColor(),n.getPiecesList());
|
||||
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) {
|
||||
// Handle ResumeNotification
|
||||
} else if (notification instanceof RollDiceNotification) {
|
||||
// Handle RollDiceNotification
|
||||
} else if (notification instanceof SelectableCardsNotification) {
|
||||
// Handle SelectableCardsNotification
|
||||
} else if (notification instanceof SelectablePiecesNotification) {
|
||||
// Handle SelectablePiecesNotification
|
||||
} else if (notification instanceof ShieldActiveNotification) {
|
||||
ShieldActiveNotification n = (ShieldActiveNotification)notification;
|
||||
gameView.getBoardHandler().shieldPiece(n.getPieceId());
|
||||
@@ -120,10 +122,14 @@ private void handleGame(Notification notification) {
|
||||
gameView.getBoardHandler().suppressShield(n.getPieceId());
|
||||
} else if (notification instanceof StartDialogNotification) {
|
||||
app.enter(MdgaState.MAIN);
|
||||
} else if (notification instanceof SwapPieceNotification) {
|
||||
// Handle SwapPieceNotification
|
||||
} else if (notification instanceof SwapPieceNotification n) {
|
||||
gameView.getBoardHandler().swapPieces(n.getFirstPiece(), n.getSecondPiece());
|
||||
} else if (notification instanceof 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 {
|
||||
throw new RuntimeException("notification not expected: " + notification.toString());
|
||||
}
|
||||
|
||||
@@ -42,13 +42,19 @@ public class BoardHandler {
|
||||
private boolean scheduleInit = 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) {
|
||||
if(app == null) throw new RuntimeException("app is null");
|
||||
|
||||
this.isInitialised = false;
|
||||
this.app = app;
|
||||
this.fpp = fpp;
|
||||
|
||||
selectedEnemyPiece = null;
|
||||
selectedOwnPiece = null;
|
||||
initMap();
|
||||
}
|
||||
|
||||
@@ -153,7 +159,9 @@ private void addHomeNode(Map<Color, List<NodeControl>> map, Color color, AssetOn
|
||||
private float getRotationMove(Vector3f prev, Vector3f next) {
|
||||
Vector3f direction = next.subtract(prev).normalizeLocal();
|
||||
//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){
|
||||
@@ -200,6 +208,7 @@ public void addPlayer(Color color, List<UUID> uuid) {
|
||||
for (int i = 0; i < playerAssets.size(); i++){
|
||||
AssetOnMap assetOnMap = playerAssets.get(i);
|
||||
PieceControl pieceControl = displayAndControl(assetOnMap, new PieceControl(assetOnMap.rot(), app.getAssetManager(), app, fpp));
|
||||
pieceControl.setRotation(assetOnMap.rot());
|
||||
movePieceToNode(pieceControl, waitNodes.get(i));
|
||||
|
||||
pieces.put(uuid.get(i), pieceControl);
|
||||
@@ -343,11 +352,117 @@ public void deOutline(UUID uuid){
|
||||
}
|
||||
|
||||
public void outline(int index){
|
||||
infield.get(index).outline();
|
||||
// infield.get(index).outline();
|
||||
|
||||
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){
|
||||
infield.get(index).deOutline();
|
||||
|
||||
|
||||
@@ -10,17 +10,18 @@
|
||||
|
||||
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) {
|
||||
super(app, fpp);
|
||||
}
|
||||
|
||||
public void outline(){
|
||||
super.outline(OUTLINE_COLOR);
|
||||
}
|
||||
|
||||
public Vector3f getLocation(){
|
||||
return this.getSpatial().getLocalTranslation();
|
||||
}
|
||||
|
||||
public void highlight() {
|
||||
super.outline(OUTLINE_HIGHLIGHT_COLOR, OUTLINE_HIGHLIGHT_WIDTH);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,7 +30,8 @@ public class PieceControl extends OutlineControl {
|
||||
private static final ColorRGBA OUTLINE_ENEMY_COLOR = ColorRGBA.Red;
|
||||
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_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_HOVER_WIDTH = 6;
|
||||
private static final int OUTLINE_SELECT_WIDTH = 8;
|
||||
@@ -59,17 +60,19 @@ public PieceControl(float initRotation, AssetManager assetManager, MdgaApp app,
|
||||
}
|
||||
|
||||
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){
|
||||
if(rot < 0) rot =- 360;
|
||||
|
||||
Quaternion quaternion = new Quaternion();
|
||||
quaternion.fromAngleAxis((float) Math.toRadians(rot), new Vector3f(0,0,1));
|
||||
this.spatial.setLocalRotation(quaternion);
|
||||
spatial.setLocalRotation(quaternion);
|
||||
}
|
||||
|
||||
public Vector3f getLocation(){
|
||||
return this.getSpatial().getLocalTranslation();
|
||||
return spatial.getLocalTranslation();
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -80,12 +83,12 @@ protected void controlUpdate(float delta) {
|
||||
}
|
||||
|
||||
public void setLocation(Vector3f loc){
|
||||
this.getSpatial().setLocalTranslation(loc);
|
||||
this.spatial.setLocalTranslation(loc);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setSpatial(Spatial spatial){
|
||||
if(this.getSpatial() == null && spatial != null){
|
||||
if(this.spatial == null && spatial != null){
|
||||
super.setSpatial(spatial);
|
||||
initSpatial();
|
||||
}
|
||||
@@ -97,8 +100,8 @@ public void setSpatial(Spatial spatial){
|
||||
public void initSpatial(){
|
||||
setRotation(this.initRotation);
|
||||
|
||||
Node oldParent = this.spatial.getParent();
|
||||
this.parentNode.setName(this.spatial.getName() + " Parent");
|
||||
Node oldParent = spatial.getParent();
|
||||
this.parentNode.setName(spatial.getName() + " Parent");
|
||||
oldParent.detachChild(this.getSpatial());
|
||||
this.parentNode.attachChild(this.getSpatial());
|
||||
oldParent.attachChild(this.parentNode);
|
||||
@@ -133,11 +136,11 @@ public void suppressShield(){
|
||||
}
|
||||
|
||||
public void setMaterial(Material mat){
|
||||
this.spatial.setMaterial(mat);
|
||||
spatial.setMaterial(mat);
|
||||
}
|
||||
|
||||
public Material getMaterial(){
|
||||
return ((Geometry) this.spatial).getMaterial();
|
||||
return ((Geometry) getSpatial()).getMaterial();
|
||||
}
|
||||
|
||||
|
||||
@@ -166,20 +169,27 @@ public void hoverOff(){
|
||||
else deOutline();
|
||||
}
|
||||
|
||||
public void select(){
|
||||
super.outline(OUTLINE_SELECT_COLOR, OUTLINE_SELECT_WIDTH);
|
||||
public void unSelect(){
|
||||
select = false;
|
||||
if(highlight) highlight(enemy);
|
||||
else deOutline();
|
||||
}
|
||||
|
||||
public void setSelect(){
|
||||
public void select(){
|
||||
if(!selectable) return;
|
||||
select = !select;
|
||||
if(select) select();
|
||||
select = true;
|
||||
super.outline(enemy ? OUTLINE_ENEMY_SELECT_COLOR : OUTLINE_OWN_SELECT_COLOR, OUTLINE_SELECT_WIDTH);
|
||||
}
|
||||
|
||||
public void setSelectable(boolean selectable){
|
||||
this.selectable = selectable;
|
||||
}
|
||||
|
||||
public boolean isSelected() { return select; }
|
||||
|
||||
public boolean isSelectable() {
|
||||
return selectable;
|
||||
}
|
||||
|
||||
public void setHoverable(boolean hoverable) {
|
||||
this.hoverable = hoverable;
|
||||
|
||||
@@ -44,7 +44,7 @@ public void initialize(AppStateManager stateManager, Application app ) {
|
||||
|
||||
ViewPort view = app.getRenderManager().createMainView("Under gui ViewPort", overlayCam);
|
||||
view.setEnabled(true);
|
||||
view.setClearFlags(false, true, false);
|
||||
view.setClearFlags(true, true, true);
|
||||
view.attachScene(root);
|
||||
fpp.setFrameBufferFormat(Image.Format.RGBA8);
|
||||
fpp.addFilter(new ComposeFilter(backTexture));
|
||||
@@ -67,7 +67,7 @@ public void render(RenderManager rm) {
|
||||
|
||||
@Override
|
||||
public void update( float tpf ) {
|
||||
root.updateLogicalState(tpf);
|
||||
|
||||
|
||||
if (init && !cardBuffer.isEmpty()) {
|
||||
for(Spatial spatial : cardBuffer){
|
||||
@@ -75,13 +75,14 @@ public void update( float tpf ) {
|
||||
}
|
||||
cardBuffer.clear();
|
||||
}
|
||||
root.updateLogicalState(tpf);
|
||||
}
|
||||
|
||||
public void addCard(Spatial card){
|
||||
public void addSpatial(Spatial card){
|
||||
cardBuffer.add(card);
|
||||
}
|
||||
|
||||
public void deleteCard(Spatial spatial){
|
||||
public void deleteSpatial(Spatial spatial){
|
||||
root.detachChild(spatial);
|
||||
}
|
||||
|
||||
|
||||
@@ -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));
|
||||
}
|
||||
|
||||
}
|
||||
@@ -75,13 +75,32 @@ private Asset bonusToAsset(BonusCard card){
|
||||
public void addCard(BonusCard card, UUID uuid) {
|
||||
CardControl control = createCard(bonusToAsset(card), nextPos());
|
||||
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){
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -129,8 +148,6 @@ private void renderName(String name, float paddingTop, float paddingLeft, boolea
|
||||
playerNameNode.attachChild(hudText);
|
||||
}
|
||||
|
||||
|
||||
|
||||
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");
|
||||
|
||||
@@ -175,7 +192,7 @@ public void test(){
|
||||
addCard(BonusCard.TURBO, UUID.randomUUID());
|
||||
addCard(BonusCard.SWAP, UUID.randomUUID());
|
||||
|
||||
// ownCardsMap.get(uuid).outline();
|
||||
showDice();
|
||||
}
|
||||
|
||||
public Camera getCardLayerCamera() {
|
||||
@@ -185,4 +202,6 @@ public Camera getCardLayerCamera() {
|
||||
public CardLayer getCardLayer(){
|
||||
return cardLayer;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -4,10 +4,10 @@ world 0,0 90
|
||||
#tree_big 0,0 0
|
||||
|
||||
#Marine Pos
|
||||
marine 4,-5 -90
|
||||
marine 4,-4 -90
|
||||
marine 5,-4 -90
|
||||
marine 5,-5 -90
|
||||
marine 4,-5 270
|
||||
marine 4,-4 270
|
||||
marine 5,-4 270
|
||||
marine 5,-5 270
|
||||
|
||||
#Blue (Marine) wait Node
|
||||
node_wait_blue 4,-5 0
|
||||
|
||||
48703
Projekte/mdga/client/src/main/resources/Models/dice/dice.obj
Normal file
48703
Projekte/mdga/client/src/main/resources/Models/dice/dice.obj
Normal file
File diff suppressed because it is too large
Load Diff
Binary file not shown.
|
After Width: | Height: | Size: 2.8 MiB |
@@ -2,37 +2,76 @@
|
||||
|
||||
import pp.mdga.game.Color;
|
||||
|
||||
import java.util.UUID;
|
||||
|
||||
/**
|
||||
* Notification that a piece has been moved.
|
||||
*/
|
||||
public class MovePieceNotification extends Notification {
|
||||
|
||||
private Color color;
|
||||
private int nodeIndex;
|
||||
/**
|
||||
* The unique identifier of the piece being moved.
|
||||
*/
|
||||
private final UUID piece;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
* @param color the color of the piece that has been moved.
|
||||
* @param nodeIndex the index of the node the piece has been moved to.
|
||||
* The index of the node from which the piece started moving.
|
||||
* Ignored if {@code moveStart} is {@code true}.
|
||||
*/
|
||||
MovePieceNotification(Color color, int nodeIndex) {
|
||||
this.color = color;
|
||||
this.nodeIndex = nodeIndex;
|
||||
private final int startIndex;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
* @return the color of the piece that has been moved.
|
||||
* Constructs a notification for a piece infield move with {@code moveStart} set to {@code false}.
|
||||
*
|
||||
* @param piece the unique identifier of the piece
|
||||
* @param startIndex the starting node index
|
||||
* @param moveIndex the destination node index
|
||||
*/
|
||||
public Color getColor() {
|
||||
return color;
|
||||
public MovePieceNotification(UUID piece, int startIndex, int moveIndex) {
|
||||
this.piece = piece;
|
||||
this.startIndex = startIndex;
|
||||
this.moveIndex = moveIndex;
|
||||
this.moveStart = false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the index of the node the piece has been moved to.
|
||||
* @return the index of the node the piece has been moved to.
|
||||
*/
|
||||
public int getNodeIndex() {
|
||||
return nodeIndex;
|
||||
public int getMoveIndex() {
|
||||
return moveIndex;
|
||||
}
|
||||
|
||||
public int getStartIndex() {
|
||||
return startIndex;
|
||||
}
|
||||
|
||||
public UUID getPiece() {
|
||||
return piece;
|
||||
}
|
||||
|
||||
public boolean isMoveStart() {
|
||||
return moveStart;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
@@ -15,7 +15,7 @@ public class SwapPieceNotification extends Notification {
|
||||
* @param firstPiece the UUID of the first 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));
|
||||
this.firstPiece = firstPiece;
|
||||
this.secondPiece = secondPiece;
|
||||
|
||||
Reference in New Issue
Block a user