# [Java3D] Probleme bei Animation



## GlasgowKid (29. Jun 2010)

Hallo allerseits,

ich baue gerade für einen Uni-Kurs das Brettspiel "Das verrückte Labyinth" in Java3D nach. Ein Spielzug dabei ist, dass man einen Spielstein nimmt und an einer beliebigen Stelle im Brett einschieben kann, wobei ein neuer Spielstein für die nächste Runde frei wird. Das Picking und auch das reine Verschieben klappt tadellos, ich möchte es aber gerne animiert darstellen und komme mit dem Alpha-Objekt nicht ganz klar.

Es soll eine Animationsfolge entstehen:
1. Neuer Spielstein wird über einen TransparencyInterpolater eingeblendet
2. Die Spielsteine aus der Reihe des quadratischen Spielbretts werden verschoben.
3. Der überflüssige Spielstein wird wieder ausgeblendet.

Das Einblenden funktioniert auch schon, aber nur dann, wenn im Alpha-Objekt der Loop-Count auf -1 oder einem Wert über 3 oder 4 steht. Die Animation soll aber nur einmal ausgeführt werden. Ich habe versucht mit den anderen Werten rumzuspielen, insbesondere mit der Verzögerung vor und nach dem triggern, aber irgendwie bekomme ich kein gutes Gefühl für richtige Einstellungen. Was läuft da verkehrt?

Als zweite Frage, würde ich gerne wissen, wie ich mehrere Animationen hintereinander ausführen kann. Also, wie kann ich sicherstellen, dass die nächste Animation erst gestartet wird, wenn die vorige beendet wurde. Und natürlich soll auch das Picking und der gesamte Spielverlauf quasi unterbrochen werden. Ich habe es mit der Alpha-Funktion finished() probiert, weiß aber nicht, ob das die korrekte Herangehensweise ist.

Hier der Quellcode:

```
private void playGangfeldAnimation(HashMap<String, Gangfeld> arg1) {
	BranchGroup objRoot = new BranchGroup();
	GangfeldBG pos = this.getGangfeldBG(arg1.get("Position")); // Position des einzuschiebenden Feldes
	GangfeldBG field = this.getGangfeldBG(arg1.get("Einschub")); //Einzuschiebendes Feld

	// Position wird auf transparent gesetzt
	for(Appearance app : pos.getAllAppearence(pos)) {
		app.setTransparencyAttributes(new TransparencyAttributes(TransparencyAttributes.BLENDED, 1f));
	}

	// Einzuschiebendes Feld wird eingeblendet             
	Alpha alpha = new Alpha(1, Alpha.DECREASING_ENABLE, 0, 10000, 5000, 0, 1000, 5000, 0, 1000); //TODO
	TransparencyAttributes target = new TransparencyAttributes(TransparencyAttributes.BLENDED, 1.0f);
	target.setCapability(TransparencyAttributes.ALLOW_VALUE_WRITE);
	
	TransparencyInterpolator transInt  = new TransparencyInterpolator(alpha, target);
	transInt.setSchedulingBounds(new BoundingSphere());
	transInt.setMinimumTransparency(1f);
	transInt.setMaximumTransparency(0f);
	
	for(Appearance app : field.getAllAppearence(field)) {
		app.setTransparencyAttributes(target);
	}
	objRoot.addChild(transInt);
	objRoot.addChild(field);
	this.getTrans(pos).addChild(objRoot);
	int i=0;
	while(!alpha.finished()) i++;
	System.out.println(i);
}
```


----------



## Marco13 (30. Jun 2010)

Ohne ein KSKB ist das schwierig nachzuvollziehen, nur 2 kleine Hinweise:
while(!alpha.finished()) i++;
ist "busy waiting" und sollte in keinem Fall gemacht werden. 

Und eine _threoretische_ Möglichkeit, mehrere Alphas hintereinander auszuführen wäre sowas wie

```
long start0 = 10;
long end0 = start0+10;
long start1 = end0;
long end1 = start1+10;
Alpha a0 = new Alpha(start0, end0...);
Alpha a0 = new Alpha(start1, end1...);
```
aber es stimmt, es wäre natürlich schön wenn's da eine eher "ereignisgesteuerte" Möglichkeit gäbe...


----------



## GlasgowKid (30. Jun 2010)

Hallo Marco,

vielen Dank für die Antwort. Was ist denn ein KSKB? Deine Lösung mit mehreren Alpha-Objekten gefällt mir gut. Meine Frage wäre, was du mit Start- und Endzeit des Alphaobjekts meinst oder wie ich die berechenen kann. Es gibt ja beim Erstellen des Objekts die triggerTime und die phaseDelayDuration. Der Unterschied ist mir nicht ganz klar. Und über die Methode setStartTime(long startTime)kann eine weitere Zeit gesetzt werden. Aber auch dort ist mir nicht klar was eine Startzeit von 10 bedeutet. Statt einer Endzeit gibt es ja auch nur increasingAlphaDuration und alphaAtOneDuration. Was die increasingAlphaRampDuration aussagt ist mir auch nich unklar. Das Problem der mehrfachen Animationen ließe sich so sicherlich recht gut lösen, aber warum die Animation bei einem loopCount von 1 gar nicht erst angezeigt wird, bleibt mir schleierhaft. Gibt es denn irgendwelche Erfahrungwerte wie ich die Eigenschaften des Alpha-Objekts günstig einstellen kann?

Viele Grüße,
Daniel


----------



## Marco13 (1. Jul 2010)

Ein KSKB ist das, was erscheint, wenn man mit der Maus kurz über dem ' KSKB ' stehenbleibt. 

Die Start- und Endzeit bezogen sich auf den Zeitraum, in dem das Alpha sich verändernde Werte liefern sollte. Das Alpha liefert ja ungefähr sowas wie

```
alphaAtOneDuration
1                __________________
                /                  \
               /                    \    alphaAtZeroDuration 
0 ------------/                      \----------------------
 |           |
 Start       Trigger
 
            ->   <-              ->   <-
             increasing           decreasing
             Alpha                Alpha
             Duration             Duration
```
(nicht 100% drauf festnageln, aber so in etwa)

Die Startzeit wird vom System festgelegt. Nach der 'trigger'-Zeit fängt das Alpha an, größere Werte zu liefern, die dann eine zeitlang (alphaAtOneDuration) bei 1.0 bleiben, danach gehen die Werte wieder runter auf 0 und bleiben da eine Weile. Die increasingAlphaRampDuration ist für nicht-konstante Beschleunigungen gedacht, wie genau müßte ich auch erst nachvollziehen.

Bin gerade über Draws a simple plot of a parameterized Java 3D Alpha Function to an AWT : Alpha3DJava gestolpert: Hab's nicht getestet, aber das könnte helfen, nachzuvollziehen, was das Alpha mit den jeweiligen Parametern genau macht.


----------



## GlasgowKid (4. Jul 2010)

Hallo Marco,

vielen Dank für deine Hilfe. Das kleine Programm hat mir super bei der Planung geholfen. Dass die Animation beim Loop-Count 1 nicht angezeigt wurde habe ich durch eine Trigger-Zeit von 10s gelöst, die aber in der tatsächlichen Darstellung nicht angezeigt wird. Bei einem kleineren Wert erscheint das Ergebnis der Animation sofort, bei einem größeren bemerkt man die angegebene Verzögerung. Da hilft auf jeden Fall rumspielen in 1000-Schritten mit dem Alpha-Objekt. Außerdem habe ich als Tipp bekommen die Startzeit des Alphas noch explizit an die Systemzeit anzupassen:


```
alpha.setStartTime(System.currentTimeMillis() - alpha.getTriggerTime());
```


----------

