קואורדינטות של פלאש ולולאות timeline
באופן כללי
, תכנות של תנועה אומר כתיבת סקריפט אשר בצורה חוזרת ונשנה משנה את מיקומו של movie clip . ישנם , כמובן , הרבה דרכים להזיז אובייקטים – בקו
ישר , מסביב למעגל , מעקב אחרי אובייקט אחר , בצורה רנדומלית וכו' .לא משנה מהו
סוג התנועה , לכל אלגוריתם של תנועה ישנם שני מרכיבים :
בחלק הראשון
של השיעור נלמד כיצד לבנות לולאות timeline
ולולאות movieclips , אשר ממקמים בכל פעם
מחדש את האובייקט , ובחלק השני נלמד כמה דוגמאות של חישוב תנועה וכיצד נשלב זאת עם
הלולאות של הזמן .
בשביל למקם
אובייקט על משטח דו מימדי אנחנו משתמשים בשיטה הקרטיזיאנית : מיקום אופקי
(קואורדינטת ‘x’ ) ומיקום אנכי (קואורדינטת ‘y’ ) .
ברשת הדו
מימדית הקרטיזיאנית :
-
המרכז הוא
בנקודה 0,0 (המקור של מערכת הקואורדינטות) .
- קואורדינטת y חיובית מתייחסת לנקודה מעל ציר ה-x .
- קואורדינטת y שלילית מתייחסת לנקודה מתחת ציר ה-x .
- קואורדינטת x חיובית מתייחסת לנקודה מימין ציר ה- y .
- קואורדינטת x חיובית מתייחסת לנקודה משמאל ציר ה-y .
בפלאש ,
הפינה השמאלית העליונה היא המקור של מערכת הקואורדינטות .
אבל פלאש
הפכה את ציר ה-y :
- קואורדינטת y חיובית מתייחסת לנקודה מתחת לציר ה-x .
- קואורדינטת y שלילית מתייחסת לנקודה מעל לציר ה-x .
על מנת לחשב תנועה של אובייקט , נעבוד על פי מערכת הקואורדינטות הקרטיזיאנית , אבל כאשר יגיע הזמן למקם ממש את האובייקטים על המסך , נהפוך את ציר ה-y (חיובי לשלילי ולהיפך) .
על מנת למקם
movie clip בפלאש , נגדיר את המאפיינים _x ו-_y שלו .
לדוגמא , על
מנת למקם movie clip בעל instance name – "ball"
במרכז הבמה נשתמש ב-
Ball._x=225;
Ball._y=200;
הצורך
בלולאת timeline
בשביל לשנות
מיקום של movie clip אנחנו משנים את מיקום
ה-_x
וה-_y
שלו בצורה חוזרת בכמויות קטנות .
תחשבו על
לולאת הזמן הבאה – היא בצורה חוזרת משנה את המיקום של האובייקט , וזה צריך לתת
אשליה של תנועה עם הזמן , לא ?
For (i=0 ; i<50 ; i++){
Ball._x+=10;
}
טעות . כאשר
מבוצע מעבר בין פריימים , הבמה של הסרט תתעדכן רק לאחר סיום הסקריפט . ולכן השלבים
של הלולאה לא קורים בנפרד אלא ביחד ולא נראה תנועה מדורגת . במקום זה הכדור יקפוץ
500 פיקסלים ימינה בכל פעם שהסקריפט יתבצע .
מיקום מחדש
של movie clip דורש עדכון של הבמה , ולכן לא
ניתן לבצע אנימציה של תנועה בשיטת הלולאות התכנותיות המסורתית .
על מנת
לאפשר לבמה לעדכן לאחר כל ביצוע של – ball._x+=10;
נצטרך לבצע לולאת timeline בצורה הבאה :
//פריים 1
ball._x+=10;
//פריים 2
GotoAndPlay(1);
לולאת timeline שראינו כרגע , שולטת לחלוטין ב-timeline שמכיל אותה . בזמן שהלולאה רצה , לא ניתן להציג שום
תוכן נורמלי ב-timeline הזה . על ידי מיקום ה-timeline הזה בתוך movie clip
ריק שמורכב משני פריימים ריקים , נשיג את היתרון של עדכון הבמה בין כל שני פריימים
, ומצד שני לא נקפיא את ה-timeline שאנחנו אולי נצטרך עבור
אנימציה .
כך בונים
לולאת timeline ניידת יותר , נתחיל עם סרט שכבר
יש בו movie clip של ball :
_root.ball._x +=10 ;
GotoAndPlay(1) ;
לולאות clip event
לולאות timeline אפקטיביות אך לא בהכרח אלגנטיות . מגרסא פלאש 5
ואילך אנחנו יכולים להשתמש בארוע enterFrame של כל movie clip על מנת להשיג את אותה
התוצאה . ארוע ה-enterFrame גורם לבלוק של קוד
מסויים להתרחש בכל פעם שעובר frame בסרט .
בואו וניצור
מחדש את לולאת ה-timeline כארוע enterFrame . נתחיל בסרט הקודם שכבר קיים בו אובייקט ball עם השם "ball” ב-timeline הראשי . (eventloop.fla)
OnClipEvent (enterFrame){
_root.ball._x += 10;
}
הפיכת לולאת ה-clip event
לגמישה יותר
בדוגמא האחרונה שראינו יש חיסרון : לא ניתן בצורה
תכנותית להתחיל או לעצור אותו לאחר שהוא התחיל . אנחנו רוצים ליצור ארוע שבאופן
שרירותי יוכל לעצור ולהתחיל מחדש .
על מנת לעשות זאת ניתן ליצור movie
clip ריק המכיל בתוכו עוד movie clip
ריק עם ארוע enterFrame בתוכו . ואז בצורה
דינמית אנחנו מוסיפים או מסירים את כל החבילה במקרה שנרצה להתחיל או לעצור את
הלולאה .
בואו ונבנה לולאת event ניתנת לשליטה .
לסרט שלנו כבר יש symbol- ball . (event-loop-controllable.fla).
1.
בחר ב- insert >> new symbol וצור שני movie
clips ריקים .
2. קרא לאחד process ולשני event loop .
3. בספריה , בחר את process , ואז בחר ב-options>>linkage . תיבת ה-property של ה-linkage תופיע .
4. בחר ב-export this symbol .
5. בתוך תיבת הטקסט identifier , הדפס processMoveBall , ולחץ על ok .
6. בפריים הראשון של process , מקם מופע של eventloop.
7. בחר במופע ששמת , וכתוב את הקוד הבא :
OnClipEvent (enterFrame){
_root.ball._x += 10;
}
8. חזור אל ה-timeline המרכזי וכתוב את הקוד לכפתור – "start move" :
On(release){
AttachMovie (“processMoveBall”,”processMoveBall”,5000);
}
9. כתוב את הקוד לכפתור – "stop move" :
On(release){
RemoveMovieClip(processMoveBall);
}
באיזו
מהירות תרוץ לולאת event ?
מכיוון
שלולאות של timeline ו-movieclips מתרחשים פעם בפריים , תדירות הביצוע שלהם תלוי ב-fps של הסרט . כל
דוגמאות הקוד עד עכשיו יוצאות בגישה שבכל פריים שיעבור , הכדור יזוז ב-10 פיקסלים
לצד ימין . (ball._x+=10)
ולכן הגדלת מהירות הסרט תגדיל את מהירות התנועה של הכדור . ככל שיותר פריימים
מעובדים בשניה , כך הכדור ממוקם מחדש יותר מהר כוך נראה שהוא זז יותר מהר .
זה יכול
להיות מפתה לחשב את המרחק שצריך לזוז ביחס ל-fps
של הסרט . לדוגמא , נניח שאנחנו רוצים שאובייקט יזוז 100 פיקסלים בשניה וה-fps הוא 20 .
במקרה כזה
נזיז את האובייקט 5 פיקסלים בפריים . (20 פריימים בשניה / 100 פיקסלים בשניה = 5
פיקסלים לפריים ) . לגישה הזאת יש שני פגמים עיקריים :
על מנת
להבטיח כי מבחינה תכנותית , אובייקטים ינועו באותה מהירות בכל מערכת שתפעיל אותם ,
אנחנו נחשב את המרחק של התנועה ביחס לזמן ולא ל-fps .
בואו נסתכל במערכת גמורה TimeScaleMotion.fla
שמקציבה תנועה על פי זמן .
התוכנית
מחולקת לשתי פונקציות : init() ו- movieclip() :
Function init (){
AttachMovie(“processMoveBall”,”processMoveBall”,5000);
DistancePerRound = 100;
Now = getTimer();
}
function MoveClip (theclip){
then = now;
now = getTimer();
elapsed = now – then;
numSeconds = elapsed / 1000 ;
moveAmount = distancePerSecond * numSeconds ;
theclip._x += moveAmount ;
}
-
פונקציית init() מאתחלת את תנועת ה-movieclip .
- היא מחוברת ל-processMoveBall , שקוראת לפונקציה moveclip() בכל פריים שחולף .
- הפונקציה init() מוציאה שני משתנים :
o distancePerSecond – מספר הפיקסלים שהסרט צריך לזוז בשניה .
o now – הזמן העכשווי .
-
אנחנו קוראים
ל-init() מכפתור ה-start :
On(release){
Init();
}
-
הפונקציה moveclip() מזיזה את הכדור
- בכל פעם שהפונקציה moveclip() נקראת , היא :
o קובעת כמה זמן חלף
o קובעת כמה להזיז את הכדור על סמך הזמן שחלף
o מזיזה את הכדור
-
הפונקציה moveclip() מקבלת פרמטר אחד , קישור ל-movie
clip
function moveclip (theclip){
-
בתוך moveclip() אנחנו מקליטים את הזמן האחרון שבה בוצע עיבוד של
פריים
then = now ;
-
אחר כך אנחנו
נותנים ל-now את הזמן העכשווי
Now = getTimer();
-
אחר כך אנחנו
מחשבים את הזמן שעבר בין עיבוד הפריים הקודם לעכשיו
Elapsed = now – then ;
-
עד עכשיו elapsed מדד במילישניות , הפעולה הבאה ממירה אותו לשניות
numSeconds = elapsed / 1000 ;
-
עכשיו כשאנו
יודעים כמה זמן חלף , בשניות , מאז שהפריים האחרון עבר , אנחנו נחשב את המרחק
לתזוזה
- נכפיל את המרחק לשניה בכמות השניות שחלפו
MoveAmount = distancePerSeconds * numSeconds ;
-
לדוגמא , אם
נזיז את האובייקט 100 פיקסלים בשניה , ועברו 0.14 שניות מאז שעובד הפריים האחרון
אז
MoveAmount = 100 * 0.14 ;
MoveAmount = 14 ;
-
אז נזיז את
האובייקט 14 פיקסלים בפריים הזה .
Theclip._x += moveAmount ;
-
פונקציית moveclip() נקראת על ידי enterFrame
של הקליפ eventLoop .
onClipEvent (enterFrame){
_root.moveClip(_root.ball);
}
יתרונות
של תנועה על פי זמן
-
אנחנו יכולים
לקבוע את ה-fps למה שנרצה מבלי להשפיע על
התנהגות המערכת .
- על ידי קביעת ה-fps ל-100 נניח , אנחנו יכולים להשיג אפקט של תנועה חלקה במחשבים מהירים .
- במחשבים איטיים יותר התנועה תהיה פחות חלקה אבל האובייקטים עדיין ינועו במהירות הרצויה – מאוד חשוב במשחקים , לדוגמא .