יום שבת, 29 באוקטובר 2011

קוד פתוח, והפעם - ניהול נבון של אנימציות לעצמים ודמויות במשחק



הבעיה
בכל משחק יש דמות ראשית. כשרוצים להוסיף אנימציות דברים מסתבכים. זה ידוע...

כאשר אתה מפתח משחק לבד עוד יש סיכוי שתצליח להסתדר, שהרי אתה עשית את זה בעצמך. אבל כשאתה עובד עם מעצבים גרפיים ואנימטורים, לך תצא מזה...
יש כאלה שאוהבים לעשות אנימציות עם tween של הפלאש (MotionTween או ShapeTween), ויש שאוהבים אנימציה רגילה מבוססת KeyFrame. ומה יקרה אם מתי שהוא הם יחליטו שהם רוצים לשנות את האנימציה או את אורכה?

הפתרון
הממשק שכתבתי כאן מתמודד עם הסוגיות הללו בדיוק. כל אנימציה מיוצגת על-ידי MovieClip אחד. בתוכו האנימטור / המעצב יכולים לייצר איזה אנימציה שהם רוצים: הליכה, ירייה, קפיצה, הבעות פנים למיניהן. האנימציה יכולה להיות מבוססת key frame או classic tween או כל אופן אחר שיבחר.
כל עוד זה נמצא בתוך MovieClip אחד זה לא מפריע. אין כאן הגבלה על אורך האנימציה ואין השפעה של מה שקורה בתוך האנימציה על המשחק עצמו.
הכל קורה במקביל.

הנה כל הקבצים של אפליקציית הדוגמא.

להסברים נוספים איך זה עובד, המשך לקרוא.

איך זה עובד ומה צריך לעשות?
בקוד מגדירים דמות משחק ומצרפים לה אנימציות: אנימציה בסיסית, הליכה, ריצה, התכופפות וכו'.
מגדירים לכל אנימציה שם ומוביקליפ שמקושר אליה, כך שכאשר נראה להפעיל את האנימציה המסויימת הזו נעביר את הדמות למצב (state) באותו שם המקושר לאנימציה.


_myCharacter.addAnimationComponent ("idle", new AnimationMovieClip ("C_Idle_Animation", AnimationMovieClipTypes.LOOP) );

כך למשל, לדמות myCharacter יש עכשיו state חדש בשם idle שהמוביקליפ בשם C_Idle_Animation יופעל בloop כאשר נעביר את הmyCharacter למצב הזה.

בעיות ועבודה עתידית
יש לציין כי בקוד המוביקליפים פשוט מתחלפים (אני מעלים את האנימציות הפעילות ומכניס את החדשות בעזרת addChild ו-removeChild). כך שלמעשה רק אנימציה אחת יכולה להיות פעילה בכל נקודת זמן.
זה בעייתי גם כי עלולה להיות "קפיצה" בזמן ההחלפה בין אנימציות כי המיקום של האובייקט באנימציה הקודמת לוא דוקא זהה למיקום ההתחלה של האובייקט באנימציה הבאה.
נקודה בעייתית נוספת היא שחייבים כרגע אנימציה אחת שמחוברת לשם idle. זה די פשוט לשנות את זה אבל אני חושב שבכל מקרה צריכה להיות אנימציה כזו (שגם מתנגנת בloop) ולכן לא עשיתי עבודה מיוחדת בשביל להקל על העניין הזה.

אשמח לשמוע הצעות, רעיונות ופתרונות להמשך עבודה על הקוד הזה.