Hallo Marc,
hallo und frohe weihnacht miteinander:
Ebenfalls frohe Weihnachten ebenfalls!
Oh, jeh. Ich geh deinen Quelltext mal der Reihe nach durch:
//schleife um a)herauszufinden in welche richtung der layer bewegt werden soll und b) um den layer dann halt auch zu bewegen
while ((end_XPos != curr_XPos)||(end_YPos != curr_YPos))
Wenn du hier eine Schleife notierst, wird das ganze solange ausgeführt, bis sich der div an der gewünschten Position befindet. Da dazwischen keine Pausen eingehalten werden, läuft die Bewegung mit "unendlicher Geschwindigkeit" ab (Rechenzeiten einmal vernachlässigt). Der div wird also sofort zu seiner Zilposition bewegt. Was du brauchst, ist eine if-Selektion:
if (end_XPos != curr_XPos || end_YPos != curr_YPos )
accessStyle(objectID).left = curr_XPos++;
Damit weist du der Eigenschaft "left" *zuerst* den Wert der Variablen "curr_XPos" zu und erhöst *anschließend* den Wert von "curr_XPos". Wenn also beispielsweise curr_XPos vor dieser Anweisung den Wert 12 hat, dann wird der div zur x-Koordinate 12 bewegt und danach wird der Wert von curr_XPos auf 13 gesetzt. Du willst wahrscheinlich in wirklichkeit das hier:
accessStyle(objectID).left = ++curr_XPos;
oder - was ich sinnvoller finde, da der Wert von curr_XPos ja anschließend nicht mehr gebraucht wird:
accessStyle(objectID).left = curr_XPos + 1;
accessStyle(objectID).left = curr_XPos--;
Hier genauso:
accessStyle(objectID).left = curr_XPos - 1;
accessStyle(objectID).top = curr_YPos++;
accessStyle(objectID).top = curr_YPos + 1;
accessStyle(objectID).top = curr_YPos--;
accessStyle(objectID).top = curr_YPos - 1;
test = setTimeout('movelayer('+objectID+','+end_XPos+','+end_YPos+')',scr_speed);
Das ist die "Killeranweisung":
Erstens musst du hier das L in moveLayer groß schreiben, weil du das in der Funktionsdefinition auch so gemacht hast. Das zweite S in scr_Speed natürlich genauso. An der Groß- und Kleinschreibung verzweifle ich in JavaScript auch oft.
Dann musst du dir vorstellen, was der Interpreter mit dieser Zeile machen würde: Er würde die einzelnen String-Literale und Variablen zu einem String zusammensetzen, den er dann als Anweisung interpretiert und nach einer Sekunde ausführt.
Wenn objectID == "testlayer" und end_Xpos == 100 und end_YPos == 100 ergibt das folgende Anweisung:
moveLayer(testlayer,100,100);
- testlayer ist hier als String-Literal gedacht, muss also in Anführungsstriche.
- die Parameterübergabe von scr_Pos fehlt
Richtig heißt di Zeile also so:
test = setTimeout('moveLayer("' + objectID + '",'+end_XPos+','+end_YPos+',' + scr_Speed + ')',scr_Speed);
Mit diesen Korrekturen sollte es funktionieren. Wenn ich aber schon mal dabei bin, zu Antworten, lass mich auch gleich mal meinen Senf dazu geben, wie man es IMHO einfacher machen könnte:
Wenn du unterschiedliche x- und y-Zielkoordinaten angibst, wirst du merken, dass die Bewegung zuerst diagonal verläuft, dann einen "Knick" macht und den Rest geradlienig weiterläuft. Also z.B. so:
+-------+
| START |
+-------+
\
\
\
\
\
\
\ +------+
\___________________| ZIEL |
+------+
Ich weiß jetzt nicht, ob du das nicht auch genau so wolltest, nehme es aber nicht an.
Mit dieser Funktion:
function bewegen2(objectID,xZiel,yZiel,zeit)
{
objektStyle = accessStyle(objectID); /* nur einmal Abfragen und wiederverwenden - ist IMHO eleganter */
xPos = parseInt(objektStyle.left);
yPos = parseInt(objektStyle.top);
/* schrittzahl ermitteln: Anzahl der Bewegungsschritte, die ausgeführt werden */
if (Math.abs(xZiel - xPos) > Math.abs(yZiel - yPos)) schrittzahl = Math.abs(xZiel - xPos);
else schrittzahl = Math.abs(yZiel - yPos);
/* Wenn die Bewegung zu langsam ist, kannst du sie mit
schrittzahl = Math.round(schrittzahl / 2);
schneller machen. Wichtig ist das Runden auf ganze Zahlen */
if (schrittzahl == 0) schrittzahl = 1; /* damit keine Division durch 0 entsteht */
/* xSpeed und ySpeed: Anzahl der Pixel, die das Objekt in jedem Schritt nach rechts bzw. unten verschoben wird */
xSpeed = (xZiel - xPos) / schrittzahl;
ySpeed = (yZiel - yPos) / schrittzahl;
intervall = setInterval("schrittzahl--; xPos += xSpeed; yPos += ySpeed; objektStyle.left = Math.round(xPos) + 'px'; objektStyle.top = Math.round(yPos) + 'px'; if (schrittzahl == 0) clearInterval(intervall);",zeit);
}
wird das vermieden. Allerdings musst du hier aufpassen, da alle Variablen global sind, damit sie in setInterval referenziert werden können. Wenn du das nicht willst (beispielsweise wenn sich mehrere Objekte gleichzeitig bewegen sollen), musst du die Anweisungen in setIntervall in eine eigene Funktion packen.
Viel Erfolg,
Robert