בשיעור היום ניצור את האובייקט של המטבע בתלת מימד על גבי הדפדפן שלנו , בתוך התשתית שיצרנו בשיעור הראשון כך שהמטבע ירונדר לתוך תגית הcanvas . קורס תכנות זה מתאים לתכנות משחקים מבוססי אינטרנט ולכן גם בחרתי לעשות משחק כי רוב השימושים הם עבור משחקים. ישנם גם שימושים בwebgl באתרי אינטרנט בשביל לתת גיוון עיצובי וכן רואים יותר ויותר אובייקטים שכאלו באתרים (למשל העמוד הבית של github אפשר לראות את כדור הארץ שנבנה עם threejs).
להלן רצף השיעורים בקורס תכנות משחקים – webgl
יוצרים סצנה (new Scene) עם Threejs
בשביל לייצר אווירה של תלת מימד עם Threejs נצטרך להגדיר כמה דברים שהם בסיסיים וקיימים בכל פרויקט Threejs שתעשו. והם:
- renderer – שאותו פגשנו בשיעור הקודם וגם בשיעור זה נעשה בו שימושים נוספים.
- camera – אובייקט המצלמה הוא מאפשר לנו לייצר חוויה של נקודת צפייה על הסצנה מבעד לחלון הcanvas שלנו
- scene – הסצנה היא מה שמקשרת את כל מה שנרכיב לתוכה (שלמעשה אנו נייצר סצנה של משחק של מטבע מסתובב)
והנה זה בקוד שלנו: הקובץ שהשתנה מהפעם הקודמת הוא coin.jsx
משהו חשוב שקרה, מכוון שהתרגלתי לכתוב עם react hooks שמתאים יותר לקומפוננטות מסוג פונקציה. אז בשיעור הקודם זה מה שעשיתי אבל במהלך העבודה כעת היה ברור כי מדובר ברכיב של class component אז שיניתי אותו בהתאמה. אני לא רציתי לתקן את מה שעשינו בשיעור הקודם שתראו את ההבדלים אם כבר יש לנו הזדמנות לעשות זאת 🙂
import React, { Component } from 'react'; import * as THREE from 'three'; class Coin extends Component { constructor(props) { super(props); this.state = {}; this.camera = new THREE.PerspectiveCamera(75, window.innerWidth / window.innerHeight, 1, 1000); this.scene = new THREE.Scene(); this.renderer = null; this.canvasRef = React.createRef(); } initialScene() { this.camera.position.z = 100; this.renderer = new THREE.WebGLRenderer({ canvas: this.canvasRef.current, }); this.renderer.setPixelRatio(window.devicePixelRatio); this.renderer.setSize(window.innerWidth, window.innerHeight); console.log(this.scene, this.camera); } componentDidMount() { this.initialScene(); this.renderer.render(this.scene, this.camera); } render() { return ( <canvas ref={this.canvasRef} className="canvasClass"></canvas> ) } } export default Coin;
אפשר לראות את השוני בין function component לבין class component . מכוון שאני צריך לעשות שימוש בפונקציות נוספות אז יהיה לי נוח יותר וגם נראה נקי יותר לעבוד עם class במקרה הזה, זה כמובן לא חובה עדיין אפשר לעבוד עם function component. חשוב לציין! כרגע לא תראו את האובייקט כי עוד לא ציירנו אובייקט, מה שכן קיים זה המצלמה והסצנה. בקונסול לוג אפשר לראות את האובייקטים המעניינים הללו (שורה 25).
המצלמה של Threejs
את שורה 9 אי אפשר לפספס , שורה חשובה מאד שיוצרת עבורנו את נקודת המבט שתשקיף אל תוך הסצנה שלנו. שימוש ב PerspectiveCamera מאפשר לנו למקם את נקודת כמעיין "נקודת מבט". ולכן הפרמטרים שנגדיר עם כך לפני הסדר:
- שדה ראיה אנכי (75). אם תשחקו עם זה תראו שאתם מתרחקים או מתקרבים לאובייקט בווקטור (כיוון במרחב) אנכי.
- יחס בין הגובה לרוחב של מפתח המצלמה. אם תשחקו עם זה תראו שהאובייקט מאבד את יחס הגודל שלו, למעשה הוא לא משנה את הגודל אבל זה רק האפקט של מפתח המצלמה. לכן אם רוצים לשמור על יחס תקין מומלץ לעשות את יחס זה בהתאם לרוחב גובה של המסך ולכן הגדרנו window.innerWidth / window.innerHeight
- קרבה של הסתכלות המצלמה לעבר האובייקט. במקרה שלנו 1 (points)
- התרחקות של הסתכלות המצלמה לעבר האובייקט. במקרה שלנו 1000
הערה: אם נרצה לעשות זום לאובייקט (בהמשך נגדיר אפשרויות של זום) אז המינימום קרבה יהיה 1 והמקסימום התרחקות יהיה 1000 ולכן מגדירים את שניהם.
מזכיר שוב שכרגע כל המשחקים בהגדרות לא יאפשרו לכם לראות את השינוי כי עוד אין שום אובייקט בסצנה.
הסצנה של Threejs
כרגע כל השימוש שאנחנו נעשה עם scene זה רק לאתחל אותו. בהמשך נוסיף אליו את כל מה שרק נרצה ולאט לאט הסצנה תתמלא ויהיה לנו משחק שלם.
שימושים נוספים עם Renderer
כפי אפשר לראות, עשינו כמה שימושים נוספים עם האובייקט של רנדר. למשל: this.renderer.render(this.scene, this.camera) שזהו תהליך בסיסי כי בלי זה לא ירונדרו המצלמה והסצנה שלנו לתוך הcanvas.
וכן עשינו עוד כמה שימושים בסיסיים למשל הגדרנו את הsize בשורה 21. ללא הגדרה זו יכול מאד להיות שיהיו לכם שיבושים בתצוגת האובייקטים כי יש לרנדר את כל גודל המסך כפי שהגדרנו ב perspective של המצלמה.
עוד הגדרנו את יחס הפיקסלים של המסך כשורה 22 על מנת לחדד את תצוגת האובייקטים ביחס פיקסלים מותאם למסך שהספציפי שיציג את המשחק שלנו.
יש לוודא שהשורה האחרונה (כרגע) היא השורה של רנדר כי לאחר כל השינויים שאנחנו עושים בסצנה או במצלמה אנחנו צריכים לרנדר כמובן. ולכן השורה צריכה לרוץ בסוף התהליך.
סיכום שיעור שני webgl | תכנות משחקים
אז הכי חשוב שתזכרו שכרגע עוד לא רואים כלום! אני יודע שזה פחות כייף כרגע ולכן גם השארנו קונסול לוג בקוד שתוכלו לראות שאכן יש לנו את המצלמה ואת הסצנה . וזה חלק סופר בסיסי וחשוב . וכן הקדשתי שיעור בפוסט אחד לדברים הללו . כמו כן אני מציע לכם לגשת לדוקו של Three ולקרוא קצת על האובייקטים הללו ולהכיר אותם טוב יותר . אני לא יסקור את כל האפשרויות שלהם כי יש מליון אפשרויות. אני מתמקד בבסיס כך שיהיה קל יותר ונוח יותר להרחיב את הידע שיש בסיס חזק. אז לסיכום זכרו שכל פרויקט שלכם עם three צריך לעשות שימוש בשלושת המרכיבים הללו scene , camera , renderer.