Bewegungslehre
-> Don't touch me
Aufgabenstellung:
Ein Sprite soll sich mit einem Mindestabstand von einem anderen Objekt fernhalten. |
Wenn ein Sprite mindestens eine bestimmte Distanz zu einem anderen Sprite (oder Punkt)
halten soll, so ist ist die Vorgangsweise zur Scripterstellung sehr einfach:
-
Überprüfen, ob die aktuelle Distanz ausreichend ist.
-
Wenn notwendig das Sprite wegbewegen: die Verbindungslinie zum anderen Objekt verlängern, und nix wie weg.
|
|
ad 1) die Distanz
Wer immer noch nicht auswendig weiß, wie der Pythagoras funktioniert,
oder wem es zu langweilig wird, die vielen "sqrt" und "float" zu tippen,
der kann ja diesen Handler verwenden:
on GetDistance P1, P2
xd = P2[1] - P1[1]
yd = P2[2] - P1[2]
RETURN sqrt(float(xd
* xd) + float(yd * yd))
end |
ad 2) die Distanz vergrößern
Und noch einmal will ich die 2 Möglichkeiten beschreiben, wie man
einen neuen Punkt mit vorgegebener Distanz und Richtung in Bezug auf einen
anderen Punkt berechnen kann:
a) mittels Vektor-Berechnung
momentanerVektor = aktuellerPunkt - Kreismittelpunkt
--
Tomate - Bombe
momentaneDistanz = GetDistance(aktuellerPunkt, Kreismittelpunkt)
--
Distanz zw. Tomate und Bombe
-- der Einheitsvektor (momentanerVektor/momentaneDistanz)
wird mit der gewünschten Distanz multipliziert
neuerPunkt = Kreismittelpunkt + (gewünschteDistanz
* momentanerVektor / momentaneDistanz)
b) mittels Winkelfunktionen
-- Winkel zw. Tomate und
Bombe im Bezug aufs Koordinatensystem:
momentanerWinkel = GetAngle(aktuellerPunkt - Kreismittelpunkt)
-- der finale Punkt liegt auf dem
Kreis rund um die Bombe, mit dem Radius "gewünschteDistanz"
neuerPunkt = Kreismittelpunkt + GetCirclePoint(momentanerWinkel,
gewünschteDistanz)
-- PS: GetAngle() und GetCirclePoint()
sind Handler beschrieben im Kapitel "kreisförmige
Bewegung"
Insbesondere bei beweglichen Elementen, denen das Sprite ausweichen
soll, kann man schon wieder die schönen 2 Zeilen Code hinzufügen,
die das Sprite langsam abbremsen lassen. :-)
property
pLoc, pSlowLoc, pDistance
on beginSprite
me
pLoc = sprite(me.spriteNum).
loc -- Position wird festgehalten
pSlowLoc = duplicate(pLoc) -- Position fürs Bremsen wird
festgehalten
pDistance = 100 -- eine minimale Distanz wird festgelegt
end
on exitFrame
me
ML = the mouseLoc -- der Bezugspunkt soll die Maus sein
distance = GetDistance(pLoc, ML) -- Distanz zw. Sprite und Maus
if distance < pDistance
then -- wenn das Sprite zu nah ist, dann...
if distance = 0 then distance = 0.0001
pLoc = ML - (pDistance * (ML - pLoc) / distance) -- wird ein neuer Punkt berechnet
end if
-- aber die wirkliche Position des
Sprites wird durch Verzögerunger berechnet
pSlowLoc = pSlowLoc + ((pLoc - pSlowLoc) / 6.0)
sprite(me.spriteNum).loc
= pSlowLoc
end |
Aufgabenstellung: Das Sprite soll auch wieder zurückkehren |
Ausgehend von dem letzten Script ist nur eine kleine Änderung im
exitFrame-Handler notwendig, damit das Sprite wieder zu seinem Ausgangspunkt
zurückkehrt.
on exitFrame
me
ML = the mouseLoc
distance = GetDistance(pLoc, ML)
-- das Sprite versucht
nun auf alle Fälle wieder zurückzukehren,
-- und bezieht sich deshalb
auf den Ausgangs-Punkt (pOrigLoc):
pLoc = pLoc + ((pOrigLoc - pLoc) / 6.0)
if distance < pDistance
then
if distance = 0 then distance = 0.0001
pLoc = ML - (pDistance * (ML - pLoc)
/ distance)
end if
sprite(me.spriteNum).loc
= pLoc
end |
|