לא על הנחש
שיעור 9 מתוך 14 בקורס משחק Unity: נחש בתלת־ממד של Coddy.
MoveFood() בוחרת תא כלשהו, כולל התאים שהנחש מכסה. אי אפשר לאכול מזון שמתחת לנחש עד שהנחש זז ממנו, וככל שהנחש ארוך יותר, כך זה קורה לעיתים קרובות יותר.
פתרון אחד הוא לבחור שוב עד שהתא פנוי. זה עובד בלוח ריק, אבל ככל שהלוח מתמלא צריך יותר ויותר ניסיונות, וכשלא נשאר אף תא פנוי, התהליך לא מסתיים לעולם. הפתרון היציב הוא ליצור תחילה רשימה של התאים הפנויים ולבחור אחד מהם: לכל תא פנוי יש סיכוי שווה להיבחר, ותמיד מספיקה בחירה אחת. בית קולנוע מושיב באותו אופן אורח שמגיע באיחור:
List<int> free = new List<int>();
for (int seat = 1; seat <= 40; seat++)
{
if (!taken.Contains(seat)) free.Add(seat);
}
int pick = free[Random.Range(0, free.Count)];Random.Range(0, free.Count) מחזירה אינדקס מ-0 ועד האחרון, כי הערך המרבי אינו נכלל. כדי לבנות את הרשימה, הלוח שואל את הנחש אם הוא מכסה תא: מתודה ב-Snake שבודקת את הראש ואת כל המקטעים.
אתגר
בינוני- ב־
Snake, כתובpublic bool Occupies(Vector3 cell): מחזירה true כאשרcellהיא התא של הראש או התא של אחד ממקטעי הזנב. - ב־
GameManager, הוסףusing System.Collections.Generic;ושכתב אתMoveFood(): עבור על כל התאים בלוח באמצעות x ו־z, הוסף כל תא שהנחש אינו תופס אלList<Vector3> free, והצב את האוכל בתא אקראי מתוך הרשימה.
לחץ על Play, ואז על Check. הבדיקות ממלאות את רוב הלוח בנחש ומוודאות שהאוכל עדיין מוצא את התאים הפנויים.
נסו בעצמכם
using UnityEngine;
public class GameManager : MonoBehaviour
{
public static GameManager Instance;
public Snake snake;
public GameObject foodPrefab;
private Transform food;
private int score;
void Awake()
{
Instance = this;
}
void Start()
{
food = Instantiate(foodPrefab).transform;
MoveFood();
}
public bool IsFood(Vector3 cell)
{
return cell == food.position;
}
public void Eat()
{
score++;
MoveFood();
}
void MoveFood()
{
int x = Random.Range(-snake.edge, snake.edge + 1);
int z = Random.Range(-snake.edge, snake.edge + 1);
food.position = new Vector3(x, 0f, z);
}
}
השיעור הזה כולל חידון קצר. התחילו את השיעור כדי לענות עליו ולעקוב אחרי ההתקדמות.