You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
Web-Dev-For-Beginners/translations/he/6-space-game/2-drawing-to-canvas/README.md

20 KiB

בניית משחק חלל חלק 2: ציור גיבור ומפלצות על הקנבס

ממשק ה-Canvas API הוא אחד הכלים החזקים ביותר בפיתוח אתרים ליצירת גרפיקה דינמית ואינטראקטיבית ישירות בדפדפן שלך. בשיעור הזה, נהפוך את אלמנט ה-HTML <canvas> הריק לעולם משחק מלא בגיבורים ומפלצות. חשבו על הקנבס כלוח האמנות הדיגיטלי שלכם שבו הקוד הופך לויזואלי.

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

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

שאלון לפני השיעור

שאלון לפני השיעור

הקנבס

אז מה בדיוק הוא אלמנט <canvas>? זו הפתרון של HTML5 ליצירת גרפיקה דינמית ואנימציות בדפדפנים. בניגוד לתמונות או סרטונים רגילים שהם סטטיים, הקנבס נותן לכם שליטה ברמת הפיקסלים על כל מה שמופיע על המסך. זה הופך אותו למושלם למשחקים, ויזואליזציות נתונים ואמנות אינטראקטיבית. חשבו עליו כמשטח ציור מתוכנת שבו JavaScript הופך למכחול שלכם.

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

קראו עוד על Canvas API ב-MDN.

כך בדרך כלל מצהירים עליו כחלק מגוף הדף:

<canvas id="myCanvas" width="200" height="100"></canvas>

מה הקוד הזה עושה:

  • מגדיר את מאפיין id כך שתוכלו להתייחס לאלמנט הקנבס הזה ב-JavaScript
  • קובע את הרוחב בפיקסלים כדי לשלוט בגודל האופקי של הקנבס
  • מגדיר את הגובה בפיקסלים כדי לקבוע את הממדים האנכיים של הקנבס

ציור גיאומטריה פשוטה

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

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

הרשת של הקנבס

תמונה מ-MDN

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

  1. קבלו הפניה לאלמנט הקנבס שלכם מה-DOM (בדיוק כמו כל אלמנט HTML אחר)
  2. קבלו את הקשר הרינדור הדו-ממדי זה מספק את כל שיטות הציור
  3. התחילו לצייר! השתמשו בשיטות המובנות של הקשר כדי ליצור את הגרפיקה שלכם

כך זה נראה בקוד:

// Step 1: Get the canvas element
const canvas = document.getElementById("myCanvas");

// Step 2: Get the 2D rendering context
const ctx = canvas.getContext("2d");

// Step 3: Set fill color and draw a rectangle
ctx.fillStyle = 'red';
ctx.fillRect(0, 0, 200, 200); // x, y, width, height

בואו נפרק את זה שלב אחר שלב:

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

Canvas API מתמקד בעיקר בצורות דו-ממדיות, אבל אפשר גם לצייר אלמנטים תלת-ממדיים לאתר; לשם כך, תוכלו להשתמש ב-WebGL API.

אפשר לצייר כל מיני דברים עם Canvas API כמו:

  • צורות גיאומטריות, כבר הראינו איך לצייר מלבן, אבל יש הרבה יותר שאפשר לצייר.
  • טקסט, אפשר לצייר טקסט עם כל גופן וצבע שתרצו.
  • תמונות, אפשר לצייר תמונה על בסיס נכס תמונה כמו .jpg או .png למשל.

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

טעינה וציור נכס תמונה

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

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

טעינת תמונה בסיסית

const img = new Image();
img.src = 'path/to/my/image.png';
img.onload = () => {
  // Image loaded and ready to be used
  console.log('Image loaded successfully!');
};

מה קורה בקוד הזה:

  • אנחנו יוצרים אובייקט תמונה חדש לחלוטין כדי להכיל את הדמות או הטקסטורה שלנו
  • אנחנו אומרים לו איזה קובץ תמונה לטעון על ידי הגדרת נתיב המקור
  • אנחנו מקשיבים לאירוע הטעינה כדי לדעת בדיוק מתי התמונה מוכנה לשימוש

דרך טובה יותר לטעון תמונות

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

function loadAsset(path) {
  return new Promise((resolve, reject) => {
    const img = new Image();
    img.src = path;
    img.onload = () => {
      resolve(img);
    };
    img.onerror = () => {
      reject(new Error(`Failed to load image: ${path}`));
    };
  });
}

// Modern usage with async/await
async function initializeGame() {
  try {
    const heroImg = await loadAsset('hero.png');
    const monsterImg = await loadAsset('monster.png');
    // Images are now ready to use
  } catch (error) {
    console.error('Failed to load game assets:', error);
  }
}

מה עשינו כאן:

  • עטפנו את כל לוגיקת טעינת התמונות ב-Promise כדי שנוכל לטפל בזה בצורה טובה יותר
  • הוספנו טיפול בשגיאות שמודיע לנו מתי משהו משתבש
  • השתמשנו בתחביר async/await מודרני כי הוא הרבה יותר קריא
  • הוספנו בלוקים של try/catch כדי לטפל בצורה אלגנטית בכל תקלה בטעינה

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

async function renderGameScreen() {
  try {
    // Load game assets
    const heroImg = await loadAsset('hero.png');
    const monsterImg = await loadAsset('monster.png');

    // Get canvas and context
    const canvas = document.getElementById("myCanvas");
    const ctx = canvas.getContext("2d");

    // Draw images to specific positions
    ctx.drawImage(heroImg, canvas.width / 2, canvas.height / 2);
    ctx.drawImage(monsterImg, 0, 0);
  } catch (error) {
    console.error('Failed to render game screen:', error);
  }
}

בואו נעבור על זה שלב אחר שלב:

  • אנחנו טוענים את תמונות הגיבור והמפלצת ברקע באמצעות await
  • אנחנו תופסים את אלמנט הקנבס ומקבלים את הקשר הרינדור הדו-ממדי שאנחנו צריכים
  • אנחנו ממקמים את תמונת הגיבור ממש במרכז באמצעות חישוב קואורדינטות מהיר
  • אנחנו מציבים את תמונת המפלצת בפינה השמאלית העליונה כדי להתחיל את תצורת האויבים
  • אנחנו תופסים כל שגיאה שעלולה לקרות במהלך הטעינה או הרינדור

עכשיו הזמן להתחיל לבנות את המשחק שלכם

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

מה לבנות

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

  • ספינת גיבור

    ספינת גיבור

  • 5*5 מפלצות

    ספינת מפלצת

שלבים מומלצים להתחלת הפיתוח

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

your-work/
├── assets/
│   ├── enemyShip.png
│   └── player.png
├── index.html
├── app.js
└── package.json

מה יש לכם לעבוד איתו:

  • דמויות המשחק נמצאות בתיקיית assets/ כך שהכל נשאר מאורגן
  • קובץ ה-HTML הראשי שלכם מגדיר את אלמנט הקנבס ומכין הכל
  • קובץ JavaScript שבו תכתבו את כל הקסם של רינדור המשחק שלכם
  • קובץ package.json שמגדיר שרת פיתוח כך שתוכלו לבדוק מקומית

פתחו את התיקייה הזו ב-Visual Studio Code כדי להתחיל בפיתוח. תצטרכו סביבת פיתוח מקומית עם Visual Studio Code, NPM ו-Node.js מותקנים. אם אין לכם npm מותקן במחשב, הנה איך להתקין אותו.

התחילו את שרת הפיתוח שלכם על ידי ניווט לתיקיית your-work:

cd your-work
npm start

הפקודה הזו עושה כמה דברים די מגניבים:

  • מתחילה שרת מקומי ב-http://localhost:5000 כך שתוכלו לבדוק את המשחק שלכם
  • מגישה את כל הקבצים שלכם בצורה נכונה כך שהדפדפן שלכם יוכל לטעון אותם
  • עוקבת אחרי שינויים בקבצים שלכם כך שתוכלו לפתח בצורה חלקה
  • מספקת לכם סביבת פיתוח מקצועית לבדוק הכל

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

הוסיפו קוד

הוסיפו את הקוד הנדרש ל-your-work/app.js כדי להשלים את המשימות הבאות:

  1. ציירו קנבס עם רקע שחור

    💡 כך עושים זאת: מצאו את ה-TODO ב-/app.js והוסיפו רק שתי שורות. הגדירו ctx.fillStyle לשחור, ואז השתמשו ב-ctx.fillRect() שמתחיל ב-(0,0) עם ממדי הקנבס שלכם. פשוט!

  2. טענו טקסטורות משחק

    💡 כך עושים זאת: השתמשו ב-await loadAsset() כדי לטעון את תמונות השחקן והאויב. שמרו אותן במשתנים כך שתוכלו להשתמש בהן מאוחר יותר. זכרו הן לא יופיעו עד שתציירו אותן בפועל!

  3. ציירו את ספינת הגיבור במרכז התחתון

    💡 כך עושים זאת: השתמשו ב-ctx.drawImage() כדי למקם את הגיבור. עבור קואורדינטת x, נסו canvas.width / 2 - 45 כדי למרכז אותה, ועבור קואורדינטת y השתמשו ב-canvas.height - canvas.height / 4 כדי למקם אותה באזור התחתון.

  4. ציירו תצורה של 5×5 ספינות אויב

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

ראשית, הגדירו קבועים עבור פריסת תצורת האויבים:

const ENEMY_TOTAL = 5;
const ENEMY_SPACING = 98;
const FORMATION_WIDTH = ENEMY_TOTAL * ENEMY_SPACING;
const START_X = (canvas.width - FORMATION_WIDTH) / 2;
const STOP_X = START_X + FORMATION_WIDTH;

בואו נפרק מה הקבועים האלה עושים:

  • אנחנו מגדירים 5 אויבים בכל שורה ועמודה (רשת יפה של 5×5)
  • אנחנו מגדירים כמה מרווח לשים בין האויבים כדי שלא ייראו צפופים
  • אנחנו מחשבים כמה רחבה תהיה כל התצורה שלנו
  • אנחנו מגלים איפה להתחיל ולסיים כדי שהתצורה תיראה ממורכזת

לאחר מכן, צרו לולאות מקוננות כדי לצייר את תצורת האויבים:

for (let x = START_X; x < STOP_X; x += ENEMY_SPACING) {
  for (let y = 0; y < 50 * 5; y += 50) {
    ctx.drawImage(enemyImg, x, y);
  }
}

מה הלולאה המקוננת הזו עושה:

  • הלולאה החיצונית נעה משמאל לימין על פני התצורה שלנו
  • הלולאה הפנימית עוברת מלמעלה למטה כדי ליצור שורות מסודרות
  • אנחנו מציירים כל דמות אויב בדיוק בקואורדינטות x,y שחישבנו
  • הכל נשאר מרווח בצורה אחידה כך שזה נראה מקצועי ומאורגן

התוצאה

התוצאה הסופית צריכה להיראות כך:

מסך שחור עם גיבור ו-5×5 מפלצות

פתרון

נסו לפתור את זה בעצמכם קודם, אבל אם אתם נתקעים, הסתכלו על הפתרון


אתגר סוכן GitHub Copilot 🚀

השתמשו במצב סוכן כדי להשלים את האתגר הבא:

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

הנחיה: צרו קובץ חדש בשם enhanced-canvas.html עם קנבס שמציג כוכבים מונפשים ברקע, פס בריאות פועם עבור ספינת הגיבור, וספינות אויב שזזות לאט כלפי מטה. כללו קוד JavaScript שמצייר כוכבים מנצנצים באמצעות מיקומים ואטימות אקראיים, מממש פס בריאות שמשנה צבע בהתאם לרמת הבריאות (ירוק > צהוב > אדום), ומנפיש את ספינות האויב לזוז למטה על המסך במהירויות שונות.

למדו עוד על מצב סוכן כאן.

🚀 אתגר

למדתם על ציור עם Canvas API שמתמקד בדו-ממד; הסתכלו על WebGL API, ונסו לצייר אובייקט תלת-ממדי.

שאלון אחרי השיעור

שאלון אחרי השיעור

סקירה ולימוד עצמי

למדו עוד על Canvas API על ידי קריאה עליו.

משימה

שחקו עם Canvas API


הצהרת אחריות:
מסמך זה תורגם באמצעות שירות תרגום AI Co-op Translator. למרות שאנו שואפים לדיוק, יש לקחת בחשבון שתרגומים אוטומטיים עשויים להכיל שגיאות או אי דיוקים. המסמך המקורי בשפתו המקורית צריך להיחשב כמקור סמכותי. עבור מידע קריטי, מומלץ להשתמש בתרגום מקצועי אנושי. אנו לא נושאים באחריות לאי הבנות או לפרשנויות שגויות הנובעות משימוש בתרגום זה.