שקף שער - המשחק הוויראלי הבא שלכם
00:00-03:00
שתף מסך עם הטלפון שלך - נסה לשחק במשחק Snake משיעור 1
"ערב טוב לכולם! מי זוכר את משחק ה-Snake שבנינו בשיעור הראשון?"
[תן לתלמידים להגיב]
"נהדר. עכשיו אני רוצה שתעשו משהו. תשלחו את הלינק לעצמכם בווטסאפ ותפתחו אותו בטלפון."
הדגם על הטלפון - נסה ללחוץ על המסך, שום דבר לא קורה
"מה קרה? הנחש לא זז. למה? כי תכנתנו אותו למקלדת. לחצנו על Spacebar, על חצים. הטלפון לא מכיר את זה."
"היום אנחנו פותרים את הבעיה הזו פעם ולתמיד. אנחנו הולכים לבנות משחק Flappy Bird - משחק שעובד גם במחשב וגם בטלפון."
"ולא רק זה. אנחנו גם נוסיף לו סאונד. אבל בלי להוריד קבצי MP3, בלי להסתבך עם זכויות יוצרים. נלמד את הסוכן שלנו להלחין."
הבעיה - המשחק לא עובד בווטסאפ
במחשב השתמשנו ב-onKeyDown - מאזין ללחיצות מקלדת.
במובייל אין מקלדת פיזית, לכן צריך onTouchStart - מאזין למגעים במסך.
"הבעיה היא פשוטה: המשחקים שבנינו עד עכשיו 'מאזינים' רק ללחיצות מקלדת."
"בקוד JavaScript יש משהו שנקרא Event Listener - זה כמו שומר שעומד ליד דלת ומחכה שמשהו יקרה."
"עד היום השומר שלנו חיכה לKeyDown - מישהו לחץ על מקש. אבל בטלפון אין מקשים!"
"היום נלמד את השומר שלנו להקשיב גם לTouchStart - מישהו נגע במסך."
Gravity - בניית מכניקת הכבידה
03:00-08:00Velocity (מהירות): מהירות התנועה של הדמות. חיובי = למטה, שלילי = למעלה.
Jump (קפיצה): הפיכת ה-Velocity לשלילי לרגע - מעיפה את הדמות למעלה.
פתח Antigravity, פרויקט חדש
"כולם פותחים Antigravity, פרויקט חדש. תקראו לו FlappyGhost."
"המשחק שלנו היום יהיה פשוט: רוח רפאים שמנסה לעוף בין צינורות. אבל יש בעיה - כוח הכבידה מושך אותה כל הזמן למטה."
הקלד את הפרומפט ולחץ Generate
"אנחנו מבקשים מהסוכן ליצור את הבסיס. שימו לב - אני מבקש שהדמות תהיה procedurally drawn. זה אומר: 'תצייר אותה בקוד, בלי תמונות'."
לחץ Preview - הרוח נופלת ומתרסקת
"תסתכלו. הרוח נופלת... נופלת... נופלת... ונפגעת. למה? כי עדיין אין לנו שליטה."
"הסוכן יצר שני משתנים חשובים: gravity - הכוח שמושך למטה, ו-velocity - המהירות בה הרוח נעה. בכל שנייה, ה-gravity מוסיף ל-velocity. ואז ה-velocity משנה את המיקום. זו פיזיקה פשוטה אבל אפקטיבית."
Touch Events - המהפכה במובייל
Touch Events: מהירים יותר ומדויקים יותר למובייל:
- touchstart - האצבע נגעה במסך
- touchmove - האצבע נעה על המסך
- touchend - האצבע עזבה את המסך
"עכשיו הרגע הקריטי. אנחנו צריכים להוסיף שליטה. אבל לא רק Spacebar - גם מגע במסך."
הקלד את הפרומפט החדש
"שימו לב להוראה: 'Bind to both Spacebar AND touchstart'. אנחנו מבקשים מהסוכן לתמוך בשני סוגי קלט."
"יש כאן גם שורה חשובה: 'Prevent default scrolling'. למה? כי בלי זה, כל פעם שנלחץ על המסך, הדף ייגלל. זה יהרוס את חוויית המשחק."
הרץ את המשחק ב-Preview, פתח Developer Tools ועבור ל-Mobile View
"הסוכן סיים. בואו נבדוק. אני פותח את כלי הפיתוח (F12), לוחץ על Toggle Device Toolbar, ובוחר iPhone."
שחק עם לחיצות עכבר שמדמות מגע
"תראו! כל לחיצה על המסך גורמת לרוח לקפוץ. זה עובד גם במחשב וגם בטלפון!"
Responsive Design - התאמה לכל מסך
08:00-12:00Viewport: אזור התצוגה בדפדפן. במובייל, צריך לוודא שהמשחק תופס את כל המסך ולא נגזר.
Full-Screen Canvas: Canvas שגודלו הוא 100% מרוחב וגובה המסך, עם יחס רוחב-גובה נכון.
"המשחק עובד, אבל יש בעיה קטנה. תסתכלו על הטלפון - המשחק לא תופס את כל המסך. יש שוליים, יש גלילה."
"זה בעיה של Responsive Design - התאמה לגודל מסך. אנחנו רוצים שהמשחק יראה מושלם בכל מכשיר."
"הסוכן כבר דאג לזה. הוא הוסיף שורה קטנה בראש הקובץ HTML:"
<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">
"השורה הזו אומרת לדפדפן: 'תתאים את הרוחב למסך, ואל תקטין'. בלי זה, הטלפון היה מנסה להציג דף מחשב מוקטן."
"בנוסף, ה-Canvas שלנו הוגדר ל-100% width ו-100% height. זה אומר: תפוס את כל המסך הזמין."
Web Audio API - סינתוז סאונד
AudioContext: ה"מנוע הסאונד" - אובייקט שמנהל את כל הצלילים. צריך ליצור אותו פעם אחת.
למה לא קובצי MP3? קבצים דורשים הורדה, שוקלים, ויש בעיות זכויות יוצרים. סינתוז = קל, מהיר, חוקי.
שחק במשחק בלי סאונד - שקט מביך
"המשחק עובד מצוין. אבל יש משהו חסר. תקשיבו..."
[שקט]
"שקט. המשחק אילם. אין פידבק קולי. זה מרגיש ריק."
"בדרך כלל, היינו צריכים לחפש באינטרנט קבצי MP3, להוריד אותם, להסתבך עם זכויות יוצרים. היום נעשה משהו אחר לגמרי."
"אני הולך ללמד את הסוכן להלחין. לא עם קבצים - עם קוד."
הקלד את הפרומפט
"אני מבקש ממנו להשתמש ב-Web Audio API. זה כלי שמובנה בכל דפדפן, שמאפשר ליצור צלילים מתמטיים."
"שלושה צלילים: Beep גבוה לקפיצה, Buzz נמוך להתנגשות, ו-Ding עליז למעבר בין צינורות."
הרץ את המשחק עם סאונד
"תקשיבו עכשיו..."
[שחק והדגם את הצלילים]
"BEEP... BEEP... DING! BZZZZ."
"זה נשמע כמו משחק ארקייד אמיתי! והכל נוצר בזמן אמיתי בדפדפן. הקובץ שלנו עדיין שוקל כמעט כלום."
Oscillator & Waveforms - גלי הקול
12:00-18:00Frequency (תדר): כמה פעמים הגל חוזר על עצמו בשנייה. תדר גבוה = צליל גבוה, תדר נמוך = צליל נמוך.
Duration (משך): כמה זמן הצליל נשמע. במשחקים: צלילים קצרים (0.1-0.3 שניות) נעימים יותר.
Sine Wave (גל סינוס): צליל רך, נקי, כמו חליל. משמש ל-Beeps פשוטים.
Square Wave (גל ריבועי): צליל קשה, כמו משחקי 8-ביט ישנים.
Sawtooth Wave (גל משונן): צליל חד, מתכתי, כמו חרירות. טוב ל-Buzzes.
Triangle Wave (גל משולש): צליל רך יותר מ-Square אבל פחות מ-Sine.
"רגע, בואו נבין מה בדיוק הסוכן עשה פה. הוא השתמש במשהו שנקרא Oscillator."
"Oscillator זה מילה מפחידה לדבר פשוט: מחולל גלים. זה כלי שמייצר גל קול בתדר מסוים."
"למשל, אם אני מבקש תדר של 440Hz, אני מקבל את הנוטה 'לה'. אם אני מבקש 880Hz, אני מקבל 'לה' גבוה יותר."
"אבל לא רק התדר חשוב - גם צורת הגל. יש ארבע צורות עיקריות:"
"1. Sine Wave - רך, נקי, כמו חליל. זה מה שהשתמשנו לקפיצה."
"2. Square Wave - קשה, כמו משחקי NES ישנים."
"3. Sawtooth Wave - חד, מתכתי. זה מה שהשתמשנו להתנגשות."
"4. Triangle Wave - באמצע בין Sine ל-Square."
"הסוכן בחר בחכמה: Sine לקפיצה (רך ונעים), Sawtooth להתנגשות (חד ומעצבן). זה יוצר ניגוד נעים."
Game Loop & Collision Detection
בכל פריים (frame), הלולאה עושה 4 דברים:
- Update Physics - מעדכן מיקומים (כבידה, תנועה)
- Check Collisions - בודק התנגשויות
- Update Score - מעדכן ניקוד
- Render (Draw) - מצייר הכל על המסך
AABB (Axis-Aligned Bounding Box): השיטה הפשוטה - בודקים אם הריבועים שמקיפים את הדמויות חופפים.
הנוסחה: אם (x1 < x2 + width2) AND (x1 + width1 > x2) AND אותו דבר ל-Y, יש התנגשות.
"עכשיו בואו נדבר על מה שקורה 'מאחורי הקלעים'. המשחק רץ ב-60 פריימים בשנייה."
"זה אומר שהקוד מריץ לולאה 60 פעמים בשנייה. כל פעם, הוא עושה ארבעה דברים:"
"1. Update Physics - מעדכן את מיקום הרוח בגלל הכבידה."
"2. Check Collisions - בודק אם הרוח נגעה בצינור או בקצה המסך."
"3. Update Score - מוסיף נקודה אם עברנו צינור."
"4. Render - מצייר הכל מחדש על המסך."
"זה נקרא Game Loop - לב המשחק. בלעדיו, שום דבר לא זז."
"החלק המעניין הוא זיהוי ההתנגשויות. הסוכן משתמש בשיטה שנקראת AABB - Axis-Aligned Bounding Box."
"זה אומר: תצייר ריבוע דמיוני סביב הרוח, ריבוע דמיוני סביב הצינור, ותבדוק אם הם חופפים. אם כן - Game Over."
UI & LocalStorage - הליטוש הסופי
18:00-25:00Play Again Button: כפתור שמאפשר להתחיל מחדש מיד, בלי Refresh. יוצר Game Loop אינסופי.
למה זה חשוב? Friction (חיכוך) הורג משחקים. כל שנייה שעוברת בין "נפסלתי" ל"שחקתי שוב" = סיכוי שהשחקן יעזוב.
שחק במשחק, התנגש בצינור
"אוקיי, יש לנו בעיה אחרונה. מה קורה כשאני נפסל?"
"המשחק פשוט קופא. אני צריך לעשות Refresh כדי לשחק שוב. זה מעצבן."
"בואו נתקן את זה. אני רוצה מסך Game Over מסודר, עם כפתור Play Again."
הקלד את הפרומפט
"שימו לב - אני גם מבקש שהמשחק ישמור את ה-High Score ב-LocalStorage. זוכרים את הכספת משיעור 2? אותה כספת."
הרץ את המשחק, התנגש, ראה את מסך ה-Game Over
"מושלם! עכשיו כשאני נפסל, רואים מסך מרכזי עם הניקוד. לוחצים על Play Again - והמשחק מתחיל מחדש מיד."
הצבע על ה-High Score
"ורואים את זה? High Score: 8. עכשיו אני עושה Refresh..."
[עשה Refresh]
"והשיא נשמר! המשחק זוכר אותי."
סיכום ואתגר - המשחק הוויראלי שלכם
25:00-30:00Touch Events - touchstart, touchmove, touchend למובייל
Responsive Design - התאמה לכל גודל מסך
Viewport - אזור התצוגה בדפדפן
Gravity & Velocity - פיזיקה פשוטה למשחקים
Web Audio API - יצירת סאונד בדפדפן
AudioContext - המנוע המרכזי לסאונד
Oscillator - מחולל גלי קול
Waveforms - Sine, Square, Sawtooth, Triangle
Game Loop - הלולאה המרכזית של המשחק
Collision Detection - זיהוי התנגשויות (AABB)
LocalStorage - שמירת נתונים מקומית
עצור שיתוף מסך, חזור למצלמה
"חברים, תסתכלו מה הספקנו היום:"
"בנינו משחק שעובד במחשב ובטלפון. זה לא סתם הישג - זה אומר שאתם יכולים לשלוח את המשחק שלכם לכל אחד בווטסאפ והוא יעבוד."
"הוספנו סאונד מסונתז - צלילים שנוצרו בקוד, בלי קבצים. זה אומר שהמשחק שלכם קל, מהיר, וחוקי לחלוטין."
"ובנינו Game Loop מושלם - התחלה, משחק, פסילה, התחלה מחדש. זה הלב של כל משחק ממכר."
"האתגר שלכם להיום: קחו את המשחק הזה ותשנו את כוח הכבידה. מה קורה אם הכבידה היא 0.8 במקום 0.6? מה אם היא 1.5?"
"נסו. תשחקו עם המספרים. תראו איך זה משנה את התחושה של המשחק."
"ואם אתם רוצים אתגר נוסף: תבקשו מהסוכן להוסיף עוד סוג מכשול. לא רק צינורות - אולי עננים נעים, אולי כוכבים שצריך לאסוף."
"בשיעור הבא - אנחנו לוקחים את כל המשחקים שבנינו ויוצרים מהם אתר פורטפוליו משותף שתוכלו להראות לחברים ולמשפחה."
"תודה רבה לכולם, נתראה בשיעור הבא!"