1

שקף שער - המשחק הוויראלי הבא שלכם

00:00-03:00
שיעור 5 הוא צעד משמעותי קדימה. עד כה בנינו משחקים שעובדים רק במחשב עם מקלדת. היום אנחנו פורצים את המחסום הגדול ביותר: מובייל. בנוסף, נלמד איך להוסיף סאונד למשחק - לא באמצעות קבצים, אלא באמצעות קוד שמייצר גלי קול בזמן אמיתי.
למעלה מ-60% משחקנים משחקים במובייל. אם המשחק שלכם לא עובד בטלפון, איבדתם את רוב הקהל. Flappy Bird המקורי הרוויח $50,000 ביום - כולו ממובייל.

שתף מסך עם הטלפון שלך - נסה לשחק במשחק Snake משיעור 1 "ערב טוב לכולם! מי זוכר את משחק ה-Snake שבנינו בשיעור הראשון?" [תן לתלמידים להגיב] "נהדר. עכשיו אני רוצה שתעשו משהו. תשלחו את הלינק לעצמכם בווטסאפ ותפתחו אותו בטלפון."

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

"היום אנחנו פותרים את הבעיה הזו פעם ולתמיד. אנחנו הולכים לבנות משחק Flappy Bird - משחק שעובד גם במחשב וגם בטלפון."

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

ההדגמה של המשחק שלא עובד בטלפון היא קריטית. זה צריך להרגיש כמו "אהה, יש בעיה שצריך לפתור". אם אין לך טלפון זמין, השתמש בכלי הפיתוח של הדפדפן (F12 > Toggle Device Toolbar) כדי לסמלץ מובייל.
2

הבעיה - המשחק לא עובד בווטסאפ

Event Listeners: הדרך שבה קוד JavaScript "מאזין" לפעולות משתמש.
במחשב השתמשנו ב-onKeyDown - מאזין ללחיצות מקלדת.
במובייל אין מקלדת פיזית, לכן צריך onTouchStart - מאזין למגעים במסך.
Event Listeners הם הבסיס לאינטראקטיביות באינטרנט. כל לחיצה, גלילה, מגע או תנועת עכבר יכולה להפוך ל-Event. הדפדפן "מודיע" לקוד שלנו כשמשהו קורה, ואנחנו מגדירים מה לעשות בתגובה.

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

"בקוד JavaScript יש משהו שנקרא Event Listener - זה כמו שומר שעומד ליד דלת ומחכה שמשהו יקרה."

"עד היום השומר שלנו חיכה לKeyDown - מישהו לחץ על מקש. אבל בטלפון אין מקשים!"

"היום נלמד את השומר שלנו להקשיב גם לTouchStart - מישהו נגע במסך."

3

Gravity - בניית מכניקת הכבידה

03:00-08:00
Gravity & Velocity - simulating realistic physics Gravity (כבידה): כוח קבוע שמושך את הדמות למטה. בקוד: velocity += gravity בכל פריים.

Velocity (מהירות): מהירות התנועה של הדמות. חיובי = למטה, שלילי = למעלה.

Jump (קפיצה): הפיכת ה-Velocity לשלילי לרגע - מעיפה את הדמות למעלה.
פיזיקה פשוטה במשחקים: כל פריים (60 פעמים בשנייה) מעדכנים את המהירות בגלל הכבידה, ואז מעדכנים את המיקום בגלל המהירות. זה יוצר תנועה מציאותית ונעימה לעין.
Create a Flappy Bird clone in a single index.html file. 1. Use HTML5 Canvas. 2. The character is a procedurally drawn white ghost with eyes. 3. Gravity constantly pulls the ghost down. 4. Obstacles are green pipes moving from right to left with a gap in the middle. 5. Background is dark blue gradient.

פתח Antigravity, פרויקט חדש "כולם פותחים Antigravity, פרויקט חדש. תקראו לו FlappyGhost."

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

הקלד את הפרומפט ולחץ Generate "אנחנו מבקשים מהסוכן ליצור את הבסיס. שימו לב - אני מבקש שהדמות תהיה procedurally drawn. זה אומר: 'תצייר אותה בקוד, בלי תמונות'."

לחץ Preview - הרוח נופלת ומתרסקת "תסתכלו. הרוח נופלת... נופלת... נופלת... ונפגעת. למה? כי עדיין אין לנו שליטה."

"הסוכן יצר שני משתנים חשובים: gravity - הכוח שמושך למטה, ו-velocity - המהירות בה הרוח נעה. בכל שנייה, ה-gravity מוסיף ל-velocity. ואז ה-velocity משנה את המיקום. זו פיזיקה פשוטה אבל אפקטיבית."

אם יש זמן, פתח את הקוד והראה את המשתנים gravity ו-velocity. הסבר שזה לא "קסם", זו מתמטיקה פשוטה: y += velocity; velocity += gravity; אבל אל תתעכב על זה יותר מדי - המטרה היא לא ללמד פיזיקה אלא להראות שהסוכן עושה את זה בשבילנו.
4

Touch Events - המהפכה במובייל

Touch Events - handling mobile screen interactions Click Event: קורה כשלוחצים ועוזבים את כפתור העכבר. עובד גם במובייל, אבל עם עיכוב של 300ms.

Touch Events: מהירים יותר ומדויקים יותר למובייל:
  • touchstart - האצבע נגעה במסך
  • touchmove - האצבע נעה על המסך
  • touchend - האצבע עזבה את המסך
למה יש עיכוב ב-Click? כי הדפדפן מחכה לראות אם זה Double-Tap (זום). Touch Events עוקפים את זה ונותנים תגובה מיידית. במשחקים מהירים כמו Flappy Bird, 300ms זה הבדל בין חיים למוות!
Make the controls mobile-friendly: 1. Bind the 'Jump' action to both the Spacebar AND a screen tap (touchstart). 2. Prevent default scrolling behavior on touch. 3. Make the canvas full-screen on mobile devices.

"עכשיו הרגע הקריטי. אנחנו צריכים להוסיף שליטה. אבל לא רק Spacebar - גם מגע במסך."

הקלד את הפרומפט החדש "שימו לב להוראה: 'Bind to both Spacebar AND touchstart'. אנחנו מבקשים מהסוכן לתמוך בשני סוגי קלט."

"יש כאן גם שורה חשובה: 'Prevent default scrolling'. למה? כי בלי זה, כל פעם שנלחץ על המסך, הדף ייגלל. זה יהרוס את חוויית המשחק."

הרץ את המשחק ב-Preview, פתח Developer Tools ועבור ל-Mobile View "הסוכן סיים. בואו נבדוק. אני פותח את כלי הפיתוח (F12), לוחץ על Toggle Device Toolbar, ובוחר iPhone."

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

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

Responsive Design - התאמה לכל מסך

08:00-12:00
Responsive Design - adapting to different screen sizes Responsive Design: עיצוב שמסתגל אוטומטית לגודל המסך - טלפון, טאבלט, מחשב.

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

Full-Screen Canvas: Canvas שגודלו הוא 100% מרוחב וגובה המסך, עם יחס רוחב-גובה נכון.
הטאג <meta name="viewport"> קריטי למובייל. בלעדיו, הטלפון יחשוב שהדף מיועד למחשב ויקטין אותו. נכון: <meta name="viewport" content="width=device-width, initial-scale=1.0">

"המשחק עובד, אבל יש בעיה קטנה. תסתכלו על הטלפון - המשחק לא תופס את כל המסך. יש שוליים, יש גלילה."

"זה בעיה של Responsive Design - התאמה לגודל מסך. אנחנו רוצים שהמשחק יראה מושלם בכל מכשיר."

"הסוכן כבר דאג לזה. הוא הוסיף שורה קטנה בראש הקובץ HTML:"

<meta name=\"viewport\" content=\"width=device-width, initial-scale=1.0\">

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

"בנוסף, ה-Canvas שלנו הוגדר ל-100% width ו-100% height. זה אומר: תפוס את כל המסך הזמין."

6

Web Audio API - סינתוז סאונד

Web Audio API - creating and manipulating sound in the browser Web Audio API: מערכת מובנית בכל דפדפן מודרני שמאפשרת ליצור, לעבד ולנגן סאונד באמצעות קוד JavaScript.

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

למה לא קובצי MP3? קבצים דורשים הורדה, שוקלים, ויש בעיות זכויות יוצרים. סינתוז = קל, מהיר, חוקי.
Web Audio API משמש לא רק במשחקים. DAWs (תחנות עבודה דיגיטליות) באינטרנט, סינתיסייזרים, אפקטים ווקאליים - הכל נבנה עם זה. הדפדפן הוא למעשה סינתיסייזר מלא!
Implement a sound system using the JavaScript Web Audio API (synthetic sounds only): 1. Play a short, high-frequency 'Beep' (Sine wave) when the ghost jumps. 2. Play a low-frequency 'Buzz' (Sawtooth wave) when collision occurs. 3. Play a cheerful 'Ding' when passing a pipe.

שחק במשחק בלי סאונד - שקט מביך "המשחק עובד מצוין. אבל יש משהו חסר. תקשיבו..." [שקט] "שקט. המשחק אילם. אין פידבק קולי. זה מרגיש ריק."

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

"אני הולך ללמד את הסוכן להלחין. לא עם קבצים - עם קוד."

הקלד את הפרומפט "אני מבקש ממנו להשתמש ב-Web Audio API. זה כלי שמובנה בכל דפדפן, שמאפשר ליצור צלילים מתמטיים."

"שלושה צלילים: Beep גבוה לקפיצה, Buzz נמוך להתנגשות, ו-Ding עליז למעבר בין צינורות."

הרץ את המשחק עם סאונד "תקשיבו עכשיו..." [שחק והדגם את הצלילים] "BEEP... BEEP... DING! BZZZZ."

"זה נשמע כמו משחק ארקייד אמיתי! והכל נוצר בזמן אמיתי בדפדפן. הקובץ שלנו עדיין שוקל כמעט כלום."

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

Oscillator & Waveforms - גלי הקול

12:00-18:00
Oscillator - a sound wave generator Oscillator: רכיב שמייצר גל קול בתדר מסוים (למשל: 440Hz = נוטה A).

Frequency (תדר): כמה פעמים הגל חוזר על עצמו בשנייה. תדר גבוה = צליל גבוה, תדר נמוך = צליל נמוך.

Duration (משך): כמה זמן הצליל נשמע. במשחקים: צלילים קצרים (0.1-0.3 שניות) נעימים יותר.
תדרי נוטות מוזיקליים: C4 = 261Hz, A4 = 440Hz, C5 = 523Hz. בסינתיסייזרים של אמת, יוצרים מנגינות שלמות על ידי שינוי התדר בזמן.
צורת הגל קובעת את "הצבע" של הצליל (Timbre). יש ארבע צורות עיקריות:

Sine Wave (גל סינוס): צליל רך, נקי, כמו חליל. משמש ל-Beeps פשוטים.
Square Wave (גל ריבועי): צליל קשה, כמו משחקי 8-ביט ישנים.
Sawtooth Wave (גל משונן): צליל חד, מתכתי, כמו חרירות. טוב ל-Buzzes.
Triangle Wave (גל משולש): צליל רך יותר מ-Square אבל פחות מ-Sine.
כל צורת גל היא למעשה נוסחה מתמטית שקובעת איך הלחץ האוויר משתנה בזמן. Sine = הצליל הכי טהור בטבע (מזלג כוונון). שאר הגלים = שילוב של הרמוניות.

"רגע, בואו נבין מה בדיוק הסוכן עשה פה. הוא השתמש במשהו שנקרא Oscillator."

"Oscillator זה מילה מפחידה לדבר פשוט: מחולל גלים. זה כלי שמייצר גל קול בתדר מסוים."

"למשל, אם אני מבקש תדר של 440Hz, אני מקבל את הנוטה 'לה'. אם אני מבקש 880Hz, אני מקבל 'לה' גבוה יותר."

"אבל לא רק התדר חשוב - גם צורת הגל. יש ארבע צורות עיקריות:"

"1. Sine Wave - רך, נקי, כמו חליל. זה מה שהשתמשנו לקפיצה."
"2. Square Wave - קשה, כמו משחקי NES ישנים."
"3. Sawtooth Wave - חד, מתכתי. זה מה שהשתמשנו להתנגשות."
"4. Triangle Wave - באמצע בין Sine ל-Square."

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

אם יש זמן ותלמידים מתעניינים, אפשר להראות גרף של צורות גל (חיפוש תמונות ב-Google: "waveforms sine square sawtooth"). אבל אל תתעכב יותר מדי - זה יכול להיות יבש. המטרה היא להבין את הרעיון הכללי, לא ללמד תורת מוזיקה.
8

Game Loop & Collision Detection

Game Loop - the heart of every game Game Loop: לולאה שרצה 60 פעמים בשנייה (60 FPS) ומעדכנת את כל המשחק.

בכל פריים (frame), הלולאה עושה 4 דברים:
  1. Update Physics - מעדכן מיקומים (כבידה, תנועה)
  2. Check Collisions - בודק התנגשויות
  3. Update Score - מעדכן ניקוד
  4. Render (Draw) - מצייר הכל על המסך
Game Loop משתמש ב-requestAnimationFrame - פונקציה מיוחדת שמסנכרנת את הלולאה עם קצב הרענון של המסך. זה חוסך סוללה ונותן ביצועים חלקים יותר מ-setInterval.
Collision Detection - detecting when objects touch Collision Detection: בדיקה אם שני אובייקטים נגעים זה בזה.

AABB (Axis-Aligned Bounding Box): השיטה הפשוטה - בודקים אם הריבועים שמקיפים את הדמויות חופפים.

הנוסחה: אם (x1 < x2 + width2) AND (x1 + width1 > x2) AND אותו דבר ל-Y, יש התנגשות.
AABB מהיר ופשוט, אבל לא מדויק ב-100%. לדמויות מעוגלות או מורכבות משתמשים ב-Pixel-Perfect Collision או Polygon Collision. אבל ב-99% מהמשחקים, AABB מספיק.

"עכשיו בואו נדבר על מה שקורה 'מאחורי הקלעים'. המשחק רץ ב-60 פריימים בשנייה."

"זה אומר שהקוד מריץ לולאה 60 פעמים בשנייה. כל פעם, הוא עושה ארבעה דברים:"

"1. Update Physics - מעדכן את מיקום הרוח בגלל הכבידה."
"2. Check Collisions - בודק אם הרוח נגעה בצינור או בקצה המסך."
"3. Update Score - מוסיף נקודה אם עברנו צינור."
"4. Render - מצייר הכל מחדש על המסך."

"זה נקרא Game Loop - לב המשחק. בלעדיו, שום דבר לא זז."

"החלק המעניין הוא זיהוי ההתנגשויות. הסוכן משתמש בשיטה שנקראת AABB - Axis-Aligned Bounding Box."

"זה אומר: תצייר ריבוע דמיוני סביב הרוח, ריבוע דמיוני סביב הצינור, ותבדוק אם הם חופפים. אם כן - Game Over."

9

UI & LocalStorage - הליטוש הסופי

18:00-25:00
Game Over Overlay: מסך שמופיע מעל המשחק כשנפסלים, עם הניקוד הסופי וכפתור התחלה מחדש.

Play Again Button: כפתור שמאפשר להתחיל מחדש מיד, בלי Refresh. יוצר Game Loop אינסופי.

למה זה חשוב? Friction (חיכוך) הורג משחקים. כל שנייה שעוברת בין "נפסלתי" ל"שחקתי שוב" = סיכוי שהשחקן יעזוב.
Add a 'Game Over' overlay centered on screen with: 1. Final score display 2. A 'Play Again' button that restarts the game instantly 3. Save the 'High Score' to LocalStorage and display it

שחק במשחק, התנגש בצינור "אוקיי, יש לנו בעיה אחרונה. מה קורה כשאני נפסל?"

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

"בואו נתקן את זה. אני רוצה מסך Game Over מסודר, עם כפתור Play Again."

הקלד את הפרומפט "שימו לב - אני גם מבקש שהמשחק ישמור את ה-High Score ב-LocalStorage. זוכרים את הכספת משיעור 2? אותה כספת."

הרץ את המשחק, התנגש, ראה את מסך ה-Game Over "מושלם! עכשיו כשאני נפסל, רואים מסך מרכזי עם הניקוד. לוחצים על Play Again - והמשחק מתחיל מחדש מיד."

הצבע על ה-High Score "ורואים את זה? High Score: 8. עכשיו אני עושה Refresh..." [עשה Refresh] "והשיא נשמר! המשחק זוכר אותי."

הדגם את ה-Play Again Loop כמה פעמים: שחק -> נפסל -> Play Again -> שחק. זה מראה שהמשחק "מכור". הדגש שה-High Score נשמר גם אחרי סגירת הדפדפן - זו נקודת WOW קטנה אבל משמעותית.
10

סיכום ואתגר - המשחק הוויראלי שלכם

25:00-30:00
Event Listeners - מאזינים לפעולות משתמש (Click, Touch, Key)
Touch 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?"

"נסו. תשחקו עם המספרים. תראו איך זה משנה את התחושה של המשחק."

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

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

"תודה רבה לכולם, נתראה בשיעור הבא!"

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