TypeScript
היא שפה שכבר למדתי בעבר אך זה לא כלי שאני מחזיק אותו לאורך זמן.
החלטתי להתנסות בספרייה Phaser
ביחד עם השפה - TypeScript
על מנת לבנות משחקים בדפדפן.
TypeScript
TypeScript
היא שפה מבוססת על JavaScript
אשר מתקמפלת אליה.
היא מוסיפה תכונות נוספות ל-JS
וספריות נוספות שאין ב-JS
.
כגון:
- סוגי משתנים סטטיים
- ממשקים
- מרחב שמות - NameSpaces
- מודולים
TypeSciprt היא JavaScript וההפך
כל קובץ סקריפט של
JS
יכול להתקמפל עם קבציTS
.ניתן לשנות קבצי
.js
ל-.ts
והם ייתקמפלו.
Typescript Hello World
app.ts:
1 | let message: string = 'Hello, World!'; |
TS
מאפשרת לנו ליצור משתנים אשר הסוג שלהם ידוע מראש.
התחביר : <type>
נותן לנו אפשרות לומר איזה סוג משתנה זה.
בעזרת tsc
ניתן לקמפל קבצי Typescript
.
אם מריצים קומפילציה של הקוד:
1 | tsc app.ts |
אז מתקבל הקוד JS
הבא.
app.js:
1 | var message = 'Hello, World!'; |
ובסוף ניתן להריץ את הקוד הזה בדפדפן או ב-node
:
1 | node app.js |
תמיכה ב-TypeScript
TS
נתמכת בכל סביבה ש-JS
רצה בה והיא לא תלויית דפדפן או סביבה.
ניתן להריץ אותה על דפדפנים, שרתים כגון node-js
או כל מנוע שתומך ב-JS
.
קיימת גם תמיכה בסביבות עבודה כגון Visual Studio Code
אשר אני אישית משתמש בו הרבה.
בעיתיות ב-TypeScript
לא כל טכנולוגיה היא מושלמת וצריך לדעת את החסרונות אל מול היתרונות.
שפה מהודרת:
צריך להשתמש במהדר (קומפיילר) על מנת להריץ את הקוד,
תחזוקה של קוד בין גרסאות שפה וקומפיילרים שונים לעיתים יוצרים בעיות.מנגון הריצה ומנגנון הקומפילציה הוא שונה.
זה יוצר בעיתיות, למרות שניתן לבדוק סוגי משתנים בזמן קומפילציה, זמן הריצה הוא דינאמי ועדיין ניתן לכתוב קוד ולהתבסס על משתנים דינאמיים.אינטגרציה מורכבת יותר.
יש אלגנטיות מסוימת ב-Javascript vanila
מכיוון שאין צורך בכלים חיצוניים כדי לבנות ולהריץ קוד.
בתוכניות מורכבות יותר צריך להשתמש גם ב:- שרתים - תוכנה שתריץ את הקוד שלנו במקרה ואנחנו בצד שרת.
- Bundler - משהו שמאגד את הקוד שלנו בצורה פשוטה על מנת שנוכל לשלוח אותו.
- Minifier - כדי לדחוס וליצור קוד שאינו קריא יש להשתמש בכלי שמצמצם ומשנה את הקוד.
Phaser 3
ספרייה הבנויה על JS
ו-TS
לפיתוח משחקים בדפדפן.
לספרייה יכולות רבות וזו לא רק ספרייה לציור גראפי, ניתן לעשות בספרייה:
- מערכת סצינה
- גראפיקה, תמיכה רבה בסוגים שונים כגון:
- תמונות רגילות
- טקסט
- אנימציות
- תלת מימד
- קלט ופלט
- כפתורים
- לחצנים שונים
- הדפסה לטקסט
- מערכת מצלמה
- מערכת חלקיקים
- מערכת פיזיקה
- תזוזה מחושבת בקלות
- תמיכה בתזוזה מתוכנתת - Tweens
- סאונד
ועוד….
התקנה והרצה
ההרצה של משחק Phaser3
יכולה להיות מורכבת כי היא כוללת גם הרצה של שרת ווב.
מכיוון שצריך runtime
אשר יריץ לנו את הקובץ ויביא קבצים אחרים, תמונות או משאבים.
כמו כן צריך Bundler
שייבנה לנו את הקוד וייאגד אותו כדי שנוכל לשים אותו ב-production
.
אני בחרתי ב-Parcel
בתור ה-Bundler .
Parcel
בכללי הוא כלי לבנייה של קוד עבור הווב.
נשתמש עבורו בשביל:
- לקמפל את קוד ה-
TS
. - לאגד את הקבצים שלנו לתיקייה תוצאות.
- לעלות שרת ווב כדי להריץ את המשחק שלנו.
האתר: https://parceljs.org/
תבנית למשחק עם Parcel ו-Phaser3
בשביל לכתוב רק ב-JS
יש את התבנית הזו:
https://github.com/ourcade/phaser3-parcel-template
בשביל לבנות בעזרת-TS
ניתן להשתמש בתנית הזו:
https://github.com/ourcade/phaser3-typescript-parcel-template
התבנית של הקבצים נראית ככה:
1 | . |
- package.json - קונפיגורציה למודול של המשחק.
- src - כל הקוד שלנו מוכל שם וגם קבצי ה-HTML.
- public - קבצי משאבים כגון תמונות, סאונד או מודלים
- dist - תיקייה הפלט של
Parcel
.
תריצו את הפקודה ותראו שזה עובד:
1 | parcel src/index -p 8000 |
בעיות שהיו לי עם Parcel
לקנפג את ההגדרות של הפרוייקט זה לא דבר קל, כמה דברים שהיו חסרים לי בקובץ package.json
1 | { |
החוסר שלהם גרמו לי לחלק מבעיות ביצירה של קבצי הפלט.
קובץ TsConfig
נראה אצלי כך:
1 | { |
ללמוד מדוגמאות
הרצה של משחק
index.html:
1 | <html> |
main.ts:
1 | import Phaser from 'phaser' |
המערכת מציירת על המסך בעזרת אחד משני מנועים - Canvas
או WebGL
.
ה-AUTO
בוחר את היכולת של WebGL
ואם הדפדפן לא תומך בו אז הוא ייבחר ב-Canvas
.
טעינה והצגה של תמונה
לכל סצינה יש כמה מתודות חשובות בסדר החיים שלה.
- init - יצירה של אובייקטים
כאן ניצור מחלקות או קונפיגורציות לפני הרצה וטעינה. - preload - טעינה של משאבים לזיכרון בסצינה
כאן נטען תמונות, סאונד או כל משאב שאנחנו צריכים. - create - יצירת סצינה
כאן נוסיף לסצינה אובייקטים שלPhaser
. - update - פונקצית עדכון עבור המצב של הסצינה
למשל סצינה שטוענת תמונה:
1 | export class MainScene extends Phaser.Scene { |
ה- super('MainScene')
נותן מפתח לסצינה כדי שמערכת הסצינות תדע באיזה סצינה מדובר.
ה-preload
טוען את התמונה בעזרת this.load.image
.
נותנים לפונקציית image
פרמטר ראשון שהוא המפתח של התמונה, ופרמטר שני את הנתיב לתמונה מתיקייה ה-Public.
ב-create
אנחנו מוסיפים את התמונה לאובייקט this.mCharacter
במיקום (100,100)
.
תוצאה:
שחקן קופץ
MainScene.ts:
1 | export class MainScene extends Phaser.Scene { |
בעזרת this.physics.add.sprite
נוסיף sprite
שניתן לערוך אותו כדי שמערכת הפיזיקה של פייסר תעבוד.
ה-velocity
מודד פיקסל בשנייה - ז”א 200 פיקסלים בשנייה לשני הכיוונים.collideWorldBounds
גורם לו לקפוץ אם הוא נתקע בגבולות החלון.bounce.set(1.2)
גורם לו לקפוץ בהתאם לערך.
ערך של - 1 ייגרום למהירות לא להשתנות.
ערך קטן מ-1 ייגרום למהירות לקטון עם כל קפיצה וערך גדול יותר מ-1 ייגרום לו להאיץ.
תוצאה:
Phaser
הוכיחה את עצמה כספרייה עוצמתית שניתן לתכנת משחקים בדפדפנים.
אני בספק אם הספרייה תוכל לעכל משחקים גדולים אך עבור משחקי דו מימד או משחקי תלת מימד קטנים יחסית היא מאוד הלמת.
העדפתי את השימוש ב-TypeScript
על מנת להשתמש בעיצוב עצמים.
התמיכה הזו מקלה מאוד על השימוש ותכנות מודולרי של המשחקים.
התנהגות רבה מוסתרת מאיתנו ובצדק - כדי שנוכל להתמקד בלוגיקה של המשחק ולא לוגיקה של התשתית.
תודה על הקריאה!