Merge branch 'development' into 'dev/model'

Development

See merge request progproj/gruppen-ht24/Gruppe-01!35
This commit is contained in:
Hanno Fleischer
2024-12-06 09:09:29 +00:00
24 changed files with 6039 additions and 25 deletions

View File

@@ -38,7 +38,8 @@ public enum Asset {
swapSymbol("Models/swapCard/swapSymbol.j3o", "Models/swapCard/swapCard_diff.png"), swapSymbol("Models/swapCard/swapSymbol.j3o", "Models/swapCard/swapCard_diff.png"),
shieldCard, shieldCard,
shieldSymbol("Models/shieldCard/shieldSymbol.j3o", "Models/shieldCard/shieldCard_diff.png"), shieldSymbol("Models/shieldCard/shieldSymbol.j3o", "Models/shieldCard/shieldCard_diff.png"),
dice dice,
missile("Models/missile/AVMT300.obj", "Models/missile/texture.jpg", 0.1f),
; ;
private final String modelPath; private final String modelPath;

View File

@@ -156,9 +156,9 @@ else if(boardSelect != null) {
p = UUID.randomUUID(); p = UUID.randomUUID();
gameView.getBoardHandler().addPlayer(Color.AIRFORCE,List.of(p,UUID.randomUUID(),UUID.randomUUID(),UUID.randomUUID())); gameView.getBoardHandler().addPlayer(Color.AIRFORCE,List.of(p,UUID.randomUUID(),UUID.randomUUID(),UUID.randomUUID()));
gameView.getBoardHandler().movePieceStartAnim(p,0); gameView.getBoardHandler().movePieceStartAnim(p,0);
gameView.getBoardHandler().movePieceAnim(p,0, 8); //gameView.getBoardHandler().movePieceAnim(p,0, 8);
} else { } else {
gameView.getBoardHandler().throwBombAnim(p); gameView.getBoardHandler().throwMissileAnim(p);
//gameView.getBoardHandler().movePieceStartAnim(p,0); //gameView.getBoardHandler().movePieceStartAnim(p,0);
} }

View File

@@ -74,10 +74,11 @@ public void selectCard(BonusCard card) {
this.card = card; this.card = card;
GameView gameView = (GameView) app.getView(); GameView gameView = (GameView) app.getView();
if(card != null) {
if(card == null) {
gameView.needConfirm(); gameView.needConfirm();
} else { } else {
gameView.noConfirm(); gameView.needNoPower();
} }
} }
@@ -93,14 +94,17 @@ public void confirm() {
} else if (a != null) { } else if (a != null) {
selectPiece(a); selectPiece(a);
gameView.getBoardHandler().clearSelectable(); gameView.getBoardHandler().clearSelectable();
} else if (card != null){
selectCard(card);
gameView.getGuiHandler().clearSelectableCards();
} else { } else {
throw new RuntimeException("nothing to confirm"); if(null == card) {
selectCard(null);
} else {
selectCard(card);
gameView.getGuiHandler().clearSelectableCards();
}
} }
gameView.noConfirm(); gameView.noConfirm();
gameView.noNoPower();
} }
public void selectTsk(Color color) { public void selectTsk(Color color) {

View File

@@ -89,6 +89,7 @@ private void handleGame(Notification notification) {
if (notification instanceof AcquireCardNotification n) { if (notification instanceof AcquireCardNotification n) {
guiHandler.addCardOwn(n.getBonusCard()); guiHandler.addCardOwn(n.getBonusCard());
app.getAcousticHandler().playSound(MdgaSound.BONUS);
} 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()); boardHandler.showDice(n.getColor());
@@ -127,8 +128,8 @@ private void handleGame(Notification notification) {
} else if (notification instanceof HomeMoveNotification home) { } else if (notification instanceof HomeMoveNotification home) {
boardHandler.movePieceHomeAnim(home.getPieceId(), home.getHomeIndex()); boardHandler.movePieceHomeAnim(home.getPieceId(), home.getHomeIndex());
guiHandler.hideText(); guiHandler.hideText();
} else if (notification instanceof InterruptNotification) { } else if (notification instanceof InterruptNotification notification1) {
gameView.enterInterrupt(); gameView.enterInterrupt(notification1.getColor());
} else if (notification instanceof MovePieceNotification n) { } else if (notification instanceof MovePieceNotification n) {
if(n.isMoveStart()) { if(n.isMoveStart()) {
//StartMove //StartMove
@@ -163,6 +164,7 @@ private void handleGame(Notification notification) {
} }
} else if (notification instanceof SelectableCardsNotification n) { } else if (notification instanceof SelectableCardsNotification n) {
guiHandler.setSelectableCards(n.getCards()); guiHandler.setSelectableCards(n.getCards());
gameView.needNoPower();
} else if (notification instanceof ShieldActiveNotification n) { } else if (notification instanceof ShieldActiveNotification n) {
boardHandler.shieldPiece(n.getPieceId()); boardHandler.shieldPiece(n.getPieceId());
} else if (notification instanceof ShieldSuppressedNotification n) { } else if (notification instanceof ShieldSuppressedNotification n) {

View File

@@ -113,9 +113,9 @@ public void playSound(MdgaSound sound) {
assets.add(new SoundAssetDelayVolume(SoundAsset.JET, 1.0f, 0.0f)); assets.add(new SoundAssetDelayVolume(SoundAsset.JET, 1.0f, 0.0f));
break; break;
case EXPLOSION: case EXPLOSION:
assets.add(new SoundAssetDelayVolume(SoundAsset.EXPLOSION_1, 1.0f, 4f)); assets.add(new SoundAssetDelayVolume(SoundAsset.EXPLOSION_1, 1.0f, 0f));
assets.add(new SoundAssetDelayVolume(SoundAsset.EXPLOSION_2, 1.0f, 4f)); assets.add(new SoundAssetDelayVolume(SoundAsset.EXPLOSION_2, 1.0f, 0f));
assets.add(new SoundAssetDelayVolume(SoundAsset.THUNDER, 1.0f, 4f)); assets.add(new SoundAssetDelayVolume(SoundAsset.THUNDER, 1.0f, 0f));
break; break;
case LOSE: case LOSE:
assets.add(new SoundAssetDelayVolume(SoundAsset.LOSE, 1.0f, 0.0f)); assets.add(new SoundAssetDelayVolume(SoundAsset.LOSE, 1.0f, 0.0f));
@@ -126,6 +126,12 @@ public void playSound(MdgaSound sound) {
case UI90: case UI90:
assets.add(new SoundAssetDelayVolume(SoundAsset.UI90, 1.0f, 0.0f)); assets.add(new SoundAssetDelayVolume(SoundAsset.UI90, 1.0f, 0.0f));
break; break;
case MISSILE:
assets.add(new SoundAssetDelayVolume(SoundAsset.MISSILE, 1.0f, 0.0f));
break;
case MATRIX:
assets.add(new SoundAssetDelayVolume(SoundAsset.MATRIX, 1.0f, 0.0f));
break;
default: default:
break; break;
} }

View File

@@ -36,4 +36,6 @@ public enum MdgaSound {
LOSE, LOSE,
BONUS, BONUS,
UI90, UI90,
MISSILE,
MATRIX,
} }

View File

@@ -35,6 +35,8 @@ enum SoundAsset {
UI90("ui90.ogg"), UI90("ui90.ogg"),
BONUS("bonus.ogg"), BONUS("bonus.ogg"),
LOSE("lose.ogg"), LOSE("lose.ogg"),
MISSILE("missile.ogg"),
MATRIX("matrix.wav"),
CONNECTED("connected.wav"); CONNECTED("connected.wav");
private final String path; private final String path;

View File

@@ -8,6 +8,7 @@
import com.jme3.scene.Node; import com.jme3.scene.Node;
import com.jme3.scene.control.AbstractControl; import com.jme3.scene.control.AbstractControl;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound;
public class Explosion { public class Explosion {
@@ -34,8 +35,6 @@ public Explosion(MdgaApp app, Node rootNode, Vector3f location) {
this.location = location; this.location = location;
this.mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md"); this.mat = new Material(app.getAssetManager(), "Common/MatDefs/Misc/Particle.j3md");
mat.getAdditionalRenderState().setDepthWrite(false);
mat.getAdditionalRenderState().setDepthTest(false);
} }
/** /**
@@ -56,7 +55,6 @@ private void initializeEmitter() {
fire.setParticlesPerSec(0); fire.setParticlesPerSec(0);
fire.setLocalTranslation(location); fire.setLocalTranslation(location);
fire.move(0, 0, 45);
smoke = new ParticleEmitter("Effect2", Type.Triangle,40); smoke = new ParticleEmitter("Effect2", Type.Triangle,40);
smoke.setMaterial(mat); smoke.setMaterial(mat);
@@ -74,7 +72,8 @@ private void initializeEmitter() {
smoke.setParticlesPerSec(0); smoke.setParticlesPerSec(0);
smoke.setLocalTranslation(location); smoke.setLocalTranslation(location);
smoke.move(0, 0, 45);
app.getAcousticHandler().playSound(MdgaSound.EXPLOSION);
} }
/** /**

View File

@@ -57,7 +57,7 @@ public JetAnimation(MdgaApp app, Node rootNode, UUID uuid, Vector3f targetPoint,
id = uuid; id = uuid;
explosion = new Explosion(app, rootNode, nodePoint); explosion = new Explosion(app, rootNode, targetPoint);
} }
/** /**
@@ -83,8 +83,6 @@ private void spawnJet() {
jetModel.setMaterial(mat); jetModel.setMaterial(mat);
rootNode.attachChild(jetModel); rootNode.attachChild(jetModel);
app.getAcousticHandler().playSound(MdgaSound.EXPLOSION);
} }
/** /**

View File

@@ -0,0 +1,138 @@
package pp.mdga.client.animation;
import com.jme3.material.Material;
import com.jme3.math.FastMath;
import com.jme3.math.Vector3f;
import com.jme3.renderer.RenderManager;
import com.jme3.renderer.ViewPort;
import com.jme3.renderer.queue.RenderQueue;
import com.jme3.scene.Node;
import com.jme3.scene.Spatial;
import com.jme3.scene.control.AbstractControl;
import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound;
import pp.mdga.client.board.BoardHandler;
import java.util.UUID;
public class MissileAnimation {
private final Node rootNode; // Root-Knoten, an den die Animation gehängt wird
private final MdgaApp app; // Referenz auf die Hauptanwendung
private final Vector3f start; // Startpunkt der Rakete
private final Vector3f target; // Zielpunkt der Rakete
private final float flightTime; // Gesamtdauer des Flugs
private Explosion explosion;
private Spatial missileModel; // 3D-Modell der Rakete
private UUID id;
/**
* Konstruktor für die MissileAnimation.
*
* @param app Die Hauptanwendung.
* @param rootNode Der Root-Knoten, an den die Animation gehängt wird.
* @param target Der Zielpunkt der Rakete.
* @param flightTime Die Zeit, die die Rakete für den gesamten Flug benötigt.
*/
public MissileAnimation(MdgaApp app, Node rootNode, UUID uuid, Vector3f target, float flightTime) {
this.app = app;
this.rootNode = rootNode;
this.flightTime = flightTime;
explosion = new Explosion(app, rootNode, target);
id = uuid;
this.target = target.add(new Vector3f(1.5f, -1, 0));
start = BoardHandler.gridToWorld(12, 0);
start.add(new Vector3f(0, 0, 0));
}
/**
* Startet die Raketenanimation.
*/
public void start() {
loadMissile();
app.getAcousticHandler().playSound(MdgaSound.MISSILE);
animateMissile();
}
/**
* Lädt das Raketenmodell und setzt es auf den Startpunkt.
*/
private void loadMissile() {
missileModel = app.getAssetManager().loadModel(Asset.missile.getModelPath()); // Lade das Missile-Modell
missileModel.scale(Asset.missile.getSize());
missileModel.setShadowMode(RenderQueue.ShadowMode.CastAndReceive);
Material mat = new Material(app.getAssetManager(), "Common/MatDefs/Light/Lighting.j3md");
mat.setTexture("DiffuseMap", app.getAssetManager().loadTexture(Asset.missile.getDiffPath()));
missileModel.setMaterial(mat);
missileModel.setLocalTranslation(start); // Setze Startposition
rootNode.attachChild(missileModel); // Füge das Modell zur Szene hinzu
}
/**
* Animiert die Rakete entlang einer Parabel.
*/
private void animateMissile() {
missileModel.addControl(new AbstractControl() {
private float elapsedTime = 0;
@Override
protected void controlUpdate(float tpf) {
elapsedTime += tpf;
float progress = elapsedTime / flightTime;
if (progress >= 0.95f) {
explosion.trigger();
}
if (progress >= 1) {
explosion.trigger();
// Flug abgeschlossen
rootNode.detachChild(missileModel); // Entferne Rakete nach dem Ziel
this.spatial.removeControl(this); // Entferne die Steuerung
return;
}
// Berechne die aktuelle Position entlang der Parabel
Vector3f currentPosition = computeParabolicPath(start, target, progress);
missileModel.setLocalTranslation(currentPosition);
// Passe die Ausrichtung an (Nase der Rakete zeigt in Flugrichtung)
Vector3f direction = computeParabolicPath(start, target, progress + 0.01f)
.subtract(currentPosition)
.normalizeLocal();
missileModel.lookAt(currentPosition.add(direction), Vector3f.UNIT_Y); // Z ist oben, Y ist "Up"
missileModel.rotate(0, FastMath.HALF_PI, 0);
}
@Override
protected void controlRender(RenderManager rm, ViewPort vp) {
// Keine Render-Logik benötigt
}
});
}
/**
* Berechnet eine Parabelbewegung von `start` zu `target`.
*
* @param start Der Startpunkt der Rakete.
* @param target Der Zielpunkt der Rakete.
* @param t Der Fortschritt des Flugs (0 bis 1).
* @return Die Position der Rakete entlang der Parabel.
*/
private Vector3f computeParabolicPath(Vector3f start, Vector3f target, float t) {
Vector3f midPoint = start.add(target).multLocal(0.5f); // Berechne die Mitte zwischen Start und Ziel
midPoint.addLocal(0, 0, 20); // Erhöhe den Scheitelpunkt der Parabel entlang der Z-Achse
// Quadratische Interpolation (Parabel)
Vector3f startToMid = FastMath.interpolateLinear(t, start, midPoint);
Vector3f midToTarget = FastMath.interpolateLinear(t, midPoint, target);
return FastMath.interpolateLinear(t, startToMid, midToTarget);
}
}

View File

@@ -10,6 +10,7 @@
import pp.mdga.client.Asset; import pp.mdga.client.Asset;
import pp.mdga.client.MdgaApp; import pp.mdga.client.MdgaApp;
import pp.mdga.client.acoustic.MdgaSound; import pp.mdga.client.acoustic.MdgaSound;
import pp.mdga.client.animation.MissileAnimation;
import pp.mdga.client.animation.MoveControl; import pp.mdga.client.animation.MoveControl;
import pp.mdga.client.animation.JetAnimation; import pp.mdga.client.animation.JetAnimation;
import pp.mdga.client.gui.DiceControl; import pp.mdga.client.gui.DiceControl;
@@ -201,7 +202,7 @@ private Spatial createModel(Asset asset, Vector3f pos, float rot) {
* @param y The y-coordinate on the grid * @param y The y-coordinate on the grid
* @return The corresponding world position * @return The corresponding world position
*/ */
private static Vector3f gridToWorld(int x, int y) { public 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);
} }
@@ -727,7 +728,7 @@ public void throwPieceAnim(UUID uuid){
} }
/** /**
* Animates the throwing of a piece to the next available waiting node. * Animates the throwing of a piece to the next available waiting node and plays jet animation.
* *
* @param uuid the UUID of the piece to animate * @param uuid the UUID of the piece to animate
*/ */
@@ -738,6 +739,18 @@ public void throwBombAnim(UUID uuid){
anim.start(); anim.start();
} }
/**
* Animates the throwing of a piece to the next available waiting node and plays ship animation.
*
* @param uuid the UUID of the piece to animate
*/
public void throwMissileAnim(UUID uuid){
Vector3f targetPoint = pieces.get(uuid).getLocation();
MissileAnimation anim = new MissileAnimation(app, rootNode, uuid, targetPoint, 2);
anim.start();
}
/** /**
* Animates the swapping of two pieces by swapping their positions and rotations. * Animates the swapping of two pieces by swapping their positions and rotations.
* *

View File

@@ -8,18 +8,21 @@
import pp.mdga.client.button.LabelButton; import pp.mdga.client.button.LabelButton;
import pp.mdga.client.button.MenuButton; import pp.mdga.client.button.MenuButton;
import pp.mdga.client.view.MdgaView; import pp.mdga.client.view.MdgaView;
import pp.mdga.game.Color;
public class InterruptDialog extends Dialog { public class InterruptDialog extends Dialog {
private ButtonRight forceButton; private ButtonRight forceButton;
private LabelButton label; private LabelButton label;
private String text = "";
public InterruptDialog(MdgaApp app, Node node) { public InterruptDialog(MdgaApp app, Node node) {
super(app, node); super(app, node);
forceButton = new ButtonRight(app, node, () -> app.getModelSynchronize().force(), "Erzwingen", 1); forceButton = new ButtonRight(app, node, () -> app.getModelSynchronize().force(), "Erzwingen", 1);
label = new LabelButton(app, node, "Warte auf Spieler...", new Vector2f(5.5f * 1.5f, 2), new Vector2f(0.5f, 0f), false); label = new LabelButton(app, node, "Warte auf " + text + "...", new Vector2f(5.5f * 1.5f, 2), new Vector2f(0.5f, 0f), false);
float offset = 2.8f; float offset = 2.8f;
@@ -40,4 +43,21 @@ protected void onHide() {
forceButton.hide(); forceButton.hide();
label.hide(); label.hide();
} }
public void setColor(Color color) {
switch (color) {
case AIRFORCE:
text = "Luftwaffe";
break;
case ARMY:
text = "Heer";
break;
case NAVY:
text = "Marine";
break;
case CYBER:
text = "CIR";
break;
}
}
} }

View File

@@ -131,6 +131,8 @@ public void selectCard(CardControl cardControl) {
cardControl.select(); cardControl.select();
cardSelect = getKeyByValue(bonusCardControlMap, cardControl); cardSelect = getKeyByValue(bonusCardControlMap, cardControl);
} }
app.getModelSynchronize().selectCard(cardSelect);
} }
public Camera getCardLayerCamera() { public Camera getCardLayerCamera() {

View File

@@ -20,6 +20,8 @@ public class GameView extends MdgaView {
private ButtonLeft leaveButton; private ButtonLeft leaveButton;
private ButtonRight confirmButton; private ButtonRight confirmButton;
private ButtonRight noPowerButton;
private Color ownColor = null; private Color ownColor = null;
private InterruptDialog interruptDialog; private InterruptDialog interruptDialog;
@@ -35,6 +37,8 @@ public GameView(MdgaApp app) {
confirmButton = new ButtonRight(app, guiNode, () -> app.getModelSynchronize().confirm(), "Bestätigen", 1); confirmButton = new ButtonRight(app, guiNode, () -> app.getModelSynchronize().confirm(), "Bestätigen", 1);
noPowerButton = new ButtonRight(app, guiNode, () -> app.getModelSynchronize().confirm(), "Verzichten", 1);
interruptDialog = new InterruptDialog(app, guiNode); interruptDialog = new InterruptDialog(app, guiNode);
fpp = new FilterPostProcessor(app.getAssetManager()); fpp = new FilterPostProcessor(app.getAssetManager());
@@ -65,6 +69,7 @@ public void onLeave() {
confirmButton.hide(); confirmButton.hide();
noPowerButton.hide();
app.getViewPort().removeProcessor(fpp); app.getViewPort().removeProcessor(fpp);
} }
@@ -109,6 +114,7 @@ public Color getOwnColor() {
} }
public void needConfirm() { public void needConfirm() {
noPowerButton.hide();
confirmButton.show(); confirmButton.show();
} }
@@ -116,7 +122,16 @@ public void noConfirm() {
confirmButton.hide(); confirmButton.hide();
} }
public void enterInterrupt() { public void needNoPower() {
confirmButton.hide();
noPowerButton.show();
}
public void noNoPower() {
noPowerButton.show();
}
public void enterInterrupt(Color color) {
enterOverlay(Overlay.INTERRUPT); enterOverlay(Overlay.INTERRUPT);
guiNode.detachChild(guiHandlerNode); guiNode.detachChild(guiHandlerNode);
@@ -124,6 +139,7 @@ public void enterInterrupt() {
app.getInputSynchronize().setClickAllowed(false); app.getInputSynchronize().setClickAllowed(false);
interruptDialog.setColor(color);
interruptDialog.show(); interruptDialog.show();
} }
@@ -135,6 +151,8 @@ public void leaveInterrupt() {
app.getInputSynchronize().setClickAllowed(true); app.getInputSynchronize().setClickAllowed(true);
app.getAcousticHandler().playSound(MdgaSound.START);
interruptDialog.hide(); interruptDialog.hide();
} }
} }

File diff suppressed because one or more lines are too long

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1,32 @@
# Blender MTL File: 'untitled.blend'
# Material Count: 3
newmtl Material.001
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd untiffftled.jpg
newmtl Material.002
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd untiffftled.jpg
newmtl Material.004
Ns 96.078431
Ka 0.000000 0.000000 0.000000
Kd 0.640000 0.640000 0.640000
Ks 0.500000 0.500000 0.500000
Ni 1.000000
d 1.000000
illum 2
map_Kd untiffftled.jpg

File diff suppressed because it is too large Load Diff

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB