תכנות לילדים באמצעות Game Maker/מריו/משטחים וכבידה


אובייקט משטח עריכה

משחקי פלטפורמה הם משחקים שבהם הדמויות הולכות על משטחים (פלטפורמות). לכן ניצור אובייקט platform יציב (Solid) עם דמות בגודל 32 על 32 פיקסלים, לא שקופה (Transparent). כרגע אפשר להסתפק בסתם ריבוע פשוט, ונשאיר לאחר-כך את העיצוב של המשטחים (כשנגיע לאריחים).

נשים כמה מופעים של המשטח בחדר כדי שמריו יוכל ללכת עליהם. כדי למקם את המשטחים בחדר, נוח לשנות את Snap X ואת Snap Y ל-32 (למעלה בחלון תכונות החדר).

 



  מריו ממשיך ללכת אחרי סוף המשטח במקום ליפול.




מריו צריך ליפול כשהוא לא על משטח, כמו שאנחנו ניפול אם נצעד מעבר לקצה המדרכה. מה גורם לנו ליפול כשאנחנו לא על משטח? הכבידה.

כבידה עריכה

 

כבידה זה הכוח המושך אותנו למטה, עד שאנחנו נתקלים במשהו שעוצר אותנו (כמו למשל הריצפה). מה שהכבידה עושה זה לשנות את המהירות האנכית שלנו. בשביל לראות איך זה עובד, אפשר לקחת כדור קטן (או עפרון, או כפית - לא חשוב מה) ולהחזיק אותו באויר בלי שיזוז (ככה שהמהירות שלו היא 0). ואז לעזוב אותו, ולראות איך המהירות האנכית שלו גדלה ככה שהוא זז למטה עד שהוא מתנגש במשטח.

יש שני דברים מעניינים בקשר לכבידה שחשוב לדעת.

  1. לא משנה לכבידה אם משהו הוא קטן או גדול, קל או כבד. לדוגמא, אם תפילו כפית קטנה וכף גדולה מאותו גובה, מי מהן תגיע ראשונה לרצפה? נסו ותראו!
  2. הכבידה עובדת בהדרגה: בכל רגע היא משנה את המהירות האנכית רק בקצת. ככה שמי שקופץ מהכסא לרצפה יגיע למהירות די קטנה; אבל מי שקופץ מהגג יגיע למהירות גדולה מספיק בשביל לשבור רגל או אברים אחרים. את זה אל תנסו! אבל אם יש לכם משהו שמותר לשבור, תוכלו לנסות להפיל אותו מגבהים שונים ולראות שנפילה מגובה נמוך לא משפיעה ואילו נפילה מגבוה כן. (ואם זה לא מספיק, תמיד אפשר להוסיף למהירות האנכית שלו אם זורקים אותו למטה בכוח...)

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


 

כדאי לדעת:

להגדלה של המהירות קוראים תאוצה. לתאוצה שהכבידה עושה לדברים שנמצאים באוויר קוראים "תאוצת הכבידה". תאוצת הכבידה על כדור הארץ היא בערך 10 מטרים לשניה, שזה אומר שבכל שניה שאנחנו באוויר הכבידה מגדילה את המהירות האנכית שלנו בכ-10 מטרים.

פעולת הכבידה עריכה

Game Maker יודע לעשות כבידה באמצעות פעולת הכבידה שבלשונית move  . הפעולה הזאת משנה את המהירות של הגוף בכל צעד של המשחק.

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

  1.   להוסיף למריו אירוע צעד כדי לבדוק בכל צעד אם הוא נמצא על משטח או לא.
  2.   לבדוק אם מריו באוויר באמצעות הפעולה לבדיקת מקום פנוי: לבדוק אם המיקום היחסי (Relative) של פיקסל אחד מתחת למריו (y=1) פנוי.
  3.  
      אם מריו אכן באוויר, להפעיל עליו כבידה. בחלון אפשרויות פעולת הכבידה צריך לכתוב 270 בשדה direction כדי שהכבידה תמשוך את מריו למטה. בשדה gravity צריך לכתוב את עוצמת הכבידה (כלומר, בכמה להגדיל את המהירות בכל צעד). לדעתי כדאי לכתוב שם מספר בין 0.5 ל-1; נסו מספרים שונים ותראו איזו כבידה נראית לכם מתאימה.

 



  עכשיו מריו נופל אם הוא הולך מעבר לקצה המשטח.




כדאי לשים לב שמריו יכול לעשות משהו שאנחנו לא יכולים: לשנות כיוון ומהירות בזמן שהוא באוויר. אמנם במציאות זה לא אפשרי, אבל בהרבה משחקי פלטפורמה נותנים לגיבור יכולת לשנות כיוון ומהירות באוויר, כולל מריו. לכן נשאיר את המצב כפי שהוא כרגע.

נחיתה עריכה

עכשיו כשמריו נופל, צריך שהוא ידע גם לנחות כשהוא נופל על משטח. קודם כל נסדר את החדר כך שנוכל לבדוק את הנחיתה: נוסיף עוד כמה מופעים של המשטח מתחת למשטח שיצרנו, כמו בתמונה למטה.

 



  כשמריו נופל הוא לא נעצר במשטח אלא עובר דרכו.




כדי לעצור את מריו כשהוא נופל על משטח, צריך:

  1.   להוסיף למריו אירוע התנגשות במשטח.
  2.   באירוע הזה לשנות את המהירות האנכית ל-0 כדי לעצור את הנפילה.
  3.   לשנות גם את הכבידה ל-0, כי מריו כבר לא באוויר.



  עכשיו מריו לא ממשיך ליפול דרך המשטח. אבל איפה הוא עוצר?




כשקורה למריו אירוע התנגשות עם אובייקט יציב (כמו המשטח), Game Maker מחזיר אותו למיקום הקודם שלו, כי הוא הרי לא יכול להזיז את האובייקט היציב וגם לא אמור להכנס לתוכו. המיקום הקודם הוא קצת מעל המשטח, לכן כשיש למריו אירוע התנגשות במשטח, הוא נעצר קצת מעל המשטח - בגובה בו הוא היה צעד אחד לפני ההתנגשות.

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

  1.   ללכת לאירוע ההתנגשות של מריו במשטח.
  2.   להוסיף את הפעולה לתזוזה עד נקודת המגע לפני הפעולה שבה עוצרים את מריו. בשדה direction כדאי לכתוב פשוט את המשתנה direction. כרגע הכיוון הוא למטה ולכן זה יזיז את מריו למטה עד המשטח. בהמשך, כשנתכנת את מריו לקפוץ, הכיוון יהיה לפעמים למעלה ואז זה יתאים גם להתנגשות של מריו במשטח שנמצא מעליו בזמן הקפיצה.

בשדה max לכתוב 12.


  עכשיו מריו עוצר בדיוק על המשטח.




התנגשות אופקית עריכה

מה קורה אם מריו מתנגש במשהו שנמצא לפניו ולא מתחתיו? בואו נשים עוד כמה מופעי משטח בחדר בשביל לבדוק.

 



  נסו להפיל את מריו ולהמשיך להזיז אותו ימינה בזמן הנפילה. מה קורה?




הפעולות באירוע ההתנגשות מתאימות רק להתנגשות אנכית, ולא להתנגשות אופקית. כמו שתכנתנו את התנועה האופקית באמצעות שינוי ישיר של x, נצטרך גם לטפל בהתנגשות האופקית באמצעות פעולת בדיקה במקום להשתמש באירוע התנגשות.

לכן נצטרך:

  1.   ללכת שוב לאירועי החצים.
  2.   להוסיף את הפעולה לבדיקת מקום פנוי לפני פעולת ההצבה ל-x, כדי לבדוק אם המקום שאליו רוצים לזוז הוא פנוי: בשדה x לכתוב 4 או -4 (תלוי אם זזים ימינה או שמאלה) ולסמן Relative, ובשדה objects להשאיר Only solid כדי שמריו יוכל עדיין להתנגש באובייקטים לא יציבים כמו בונוסים ואויבים.



  עכשיו מריו מחליק יפה למטה.




סידור מחדש עריכה

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

ההבדל בין הפעולות בשני אירועי החצים הוא אם מנסים להתקדם ימינה למיקום x=4 או שמאלה למיקום x=-4. אם נצליח למצוא ביטוי שיוצא 4 כשמריו פונה ימינה ו--4 כשמריו פונה שמאלה, נוכל לכתוב אותו בפעולות ואז הן יהיו זהות בשני האירועים ויהיה אפשר להעביר אותן לאירוע משתמש יחיד.

למרבה השמחה, המשתנה image_xscale שווה ל-1 כשמריו פונה ימינה, ול--1 כשמריו פונה שמאלה. לכן כל מה שצריך זה להכפיל אותו ב-4: הביטוי 4*image_xscale שווה ל-4 כשמריו פונה ימינה ול--4 כשמריו פונה שמאלה.

  לכן באירועי החצים נשנה את הערך בפעולות ל-4*image_xscale במקום 4 ו--4.



  מריו אמור להתנהג כמו קודם, כי רק שינינו את הסידור.




 

עכשיו כשהפעולות בשני האירועים זהות, אפשר להעביר אותן לאירוע משתמש:

  1.   ליצור אירוע משתמש חדש.
  2.   לכתוב הערה מה קורה באירוע הזה: אירוע: התקדמות ימינה או שמאלה.
  3.   ללכת לאחד מאירועי החצים, לבחור את הפעולות בו, ולהעתיק אותן ללוח באמצעות Control+C.
  4.   לחזור לאירוע המשתמש ולהדביק שם את הפעולות באמצעות Control+V.
  5.   ללכת שוב לאירועי החצים, לבחור את הפעולות, ולמחוק אותן באמצעות Delete.
  6.   במקומן להוסיף פעולת קוד ובחלון הקוד לכתוב event_user(0); כדי להפעיל את אירוע המשתמש.



  מריו עדיין אמור להתנהג כמו קודם כי רק עשינו סידור מחדש.




- משטחים וכבידה
תרגילים
-