תכנות לילדים באמצעות Game Maker/פק-מן/צעד 9: תנועה חכמה


משתני הקורדינטות

עריכה

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

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

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

הבעיה היא שאנחנו לא רוצים את x של האובייקט שלנו, של הצל. אנחנו צריכים את x (ואת y) של פקמן, כדי להגיד לצל לנוע לכיוונו. הפתרון של Game Maker לבעיה הזאת הוא לאפשר לנו להגיד שאנחנו רוצים x של אובייקט אחר. איך אומרים את זה? ככה: pacman.x כשאנחנו כותבים לפני שם המשתנה (x) את שם האובייקט (pacman) וביניהם שמים נקודה, Game Maker יבין שאנחנו מתכוונים למשתנה של האובייקט שאותו כתבנו.

לכן צריך לכתוב pacman.x בשדה x, ו-pacman.y בשדה y.

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

משתנה הכיוון

עריכה
 

כדי ליישר את כיוון התנועה נצטרך לשנות עוד משתנה: direction. המשתנה הזה קובע את כיוון התנועה של האובייקט. הערך שלו הוא מספר המעלות של כיוון האובייקט ביחס לתנועה ימינה. אנחנו צריכים שהערך של המשתנה direction יהיה אחד מהמספרים 0 (ימינה), 90 (למעלה), 180 (שמאלה) או 270 (למטה).

בשביל לשנות את הערך של המשתנה direction צריך להוסיף פעולה נוספת אחרי פעולת התנועה - פעולת קביעת ערך של משתנה, שנמצאת בלשונית control:  .

 

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

המשתנה שצריך לקבוע את הערך שלו זה משתנה הכיוון direction. אבל מה צריך להיות הערך שנותנים לו? בואו נמצא את זה לאט-לאט. אם קשה לך להבין, לא נורא; אפשר להסתדר גם בלי להבין בדיוק.

אנחנו צריכים לשנות את הערך של משתנה הכיוון direction כדי שיהיה אחד מהכיוונים הישרים: 0, 90, 180, או 270. כלומר, צריך לעגל את הערך של direction לכפולה של 90.


 

כדאי לדעת:

כשאומרים "לעגל" מספר אין לזה קשר לעיגול. הכוונה היא למצוא את "המספר העגול" הכי קרוב. מה זה "מספר עגול"? זה תלוי בהקשר. בהקשר שלנו, למשל, הכוונה למספר מעלות שנותן כיוון לא אלכסוני. בהקשרים אחרים, מתכוונים למספר שלם - מספר שאין לו ספרות אחרי הנקודה העשרונית. למשל, אם מעגלים את המספר 2.3 מקבלים 2, ואם מעגלים 5.9 מקבלים 6. יש עוד הקשרים, אבל הם כרגע לא חשובים לנו.

ב-Game Maker יש פונקציה שמעגלת מספר כלשהו למספר השלם הקרוב ביותר: הפונקציה round (רַאוּנְד) - עַגֵּל. למשל, אם נכתוב round(2.8) אז Game Maker יציב במקום זה את התוצאה של הפונקציה: 3.

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

  1. נחלק את הכיוון ב-90. אז אם הכיוון היה ימינה (0 מעלות) נקבל 0, אם הכיוון היה למעלה למעלה (90 מעלות) נקבל 1, אם שמאלה (180 מעלות) נקבל 2, ואם למטה (270 מעלות) נקבל 3. במלים אחרות, הביטוי direction/90 (כלומר, הכיוון לחלק ל-90) ייתן לנו מספר בין 0 ל-4, שבו הכיוונים הישרים הופכים בדיוק למספרים השלמים. כיוונים אחרים יהפכו למספרים לא שלמים (למשל, כיוון 45 יהפוך ל-0.5).
  2. נעגל את המספר שקיבלנו באמצעות הפונקציה round. מה שיצא יהיה הביטוי: round( direction/90 ). ככה שאם קיבלנו קודם 3.1 זה יהפוך ל-3, ואם קיבלנו 0.7 זה יהפוך ל-1.
  3. ולבסוף, נכפיל את התוצאה ב-90, כדי ששוב יהיה לנו כיוון במעלות: 90 * round( direction/90 ) (הסימן * מסמן פעולת כפל). ככה שאם בשלב הקודם היה לנו 1, אז נקבל עכשיו 90, אם היה 2 אז נקבל 180, וכן הלאה.

השורה התחתונה: נכתוב בשדה הערך את הביטוי 90 * round( direction/90 ) וככה נהפוך את הכיוון האלכסוני לכיוון הישר הקרוב ביותר.


  איך הצל נע עכשיו?




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


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




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


  עכשיו הצל אמור לרדוף אחרי פקמן יותר מוקדם במשחק.




חוכמות אחרות

עריכה

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

במקום זה, נוסיף עוד רוח אחת: speedy (סְפִּידִי) - מהיר. בפקמן המקורי, זו הרוח הורודה. היא מנסה להגיע לא למיקום של פקמן, אלא למיקום שנמצא כמה משבצות לפניו.

 

עכשיו תורכם:

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

כדי שספידי ינוע למיקום שלפני פקמן, צריך לשנות את פעולת התנועה לנקודה שהוא עושה בארוע הצעד. במקום שהוא ינוע לנקודה שה-x שלה הוא pacman.x וה-y שלה הוא pacman.y (המיקום של פקמן), צריך לכוון אותו לנקודה שנמצאת כמה משבצות לפני פקמן: נקודה שה-x שלה הוא pacman.x ועוד משהו או פחות משהו (תלוי אם פקמן מתקדם ימינה או שמאלה), וה-y שלה הוא pacman.y ועוד משהו או פחות משהו (תלוי אם פקמן מתקדם למטה או למעלה).

איך נדע מה להוסיף ל-pacman.x ול-pacman.y? בשביל זה נשתמש בעוד שני משתנים:

  • hspeed זה קיצור של horizontal speed (הוֹרִיזוֹנְטַל סְפִּיד) - מהירות אופקית, כלומר המהירות ימינה או שמאלה. אם פקמן נע ימינה, המהירות האופקית שלו תהיה מספר חיובי (למשל 4) ואם הוא נע שמאלה אז המהירות האופקית שלו תהיה מספר שלילי (למשל -4).
  • vspeed זה קיצור של vertical speed (וֵרְטִיקַל סְפִּיד) - מהירות אנכית, כלומר המהירות למטה או למעלה. אם פקמן נע למטה, המהירות האנכית שלו תהיה מספר חיובי (למשל 4) ואם הוא נע למעלה אז המהירות האנכית שלו תהיה מספר שלילי (למשל -4).

אם נוסיף ל-pacman.x את המשתנה pacman.hspeed, נקבל מקום שנמצא כמה פיקסלים לפני פקמן בכיוון האופקי. ואם נוסיף ל-pacman.x את הביטוי pacman.hspeed * 32 נקבל מקום שנמצא כמה משבצות לפני פקמן בכיוון האופקי. לכן, בפעולת התנועה לכיוון נקודה של ספידי, נכתוב בשדה x את הביטוי:
pacman.x + pacman.hspeed * 32
בדומה, בשדה y נכתוב את הביטוי:
pacman.y + pacman.vspeed * 32


  נסו למשוך את ספידי לרדוף אחרי פקמן ואחר כך לברוח ממנו.




עכשיו המשחק כבר לא כל כך קל. אפשר להשאיר אותו עם שלוש רוחות, ואפשר גם להוסיף רוח נוספת, כמו שיש בפקמן המקורי. אני אשאיר את זה לבחירתך.

 

עכשיו תורכם:

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

עדכון רשימת העבודה

עריכה

המצב שלנו עכשיו בתהליך העבודה הוא זה:

  • פקמן
  • קירות המבוך
  • נקודות שפקמן אוכל
  • פירות
  • רוחות
  • כדורי כוח
  • עוד מבוכים
  • (אולי) להוסיף חפצי בונוס שווים יותר למבוכים המתקדמים
  • (אולי) להאיץ את מהירות התנועה

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