Menu
CoddyTech

מסך פתיחה

שיעור 20 מתוך 21 בקורס משחק Unity: מסלולי שמיים של Coddy.

למשחק יש התחלה: הוא נפתח במסך כותרת עם השם, הניקוד הגבוה ביותר וההנחיה לקפוץ כדי להתחיל. הדרך נשארת ללא תנועה והמקשים לא עושים דבר עד שמקש קפיצה (Space או W) מתחיל את הריצה.

לשם כך דרוש מצב נוסף לצד over: running. הוא מתחיל כ-false, קפיצה משנה אותו ל-true, ו-GameOver משנה אותו שוב ל-false. \n בהודעה מתחיל שורה חדשה:

messageText.text = "My Game\nBest: " + PlayerPrefs.GetInt("BestScore", 0) + "\nPress to start";

כל מה שב-Update שמניע את המשחק מופיע אחרי if (!running) return;, כך שבמסך הכותרת שום דבר לא זז.

challenge icon

אתגר

בינוני

פתח את המשחק במסך פתיחה שממתין לקפיצה.

  1. ב־GameManager הוסף public bool running;. ב־Start הגדר speed = 0f ואת messageText.text = "Sky Lanes\nBest: " + PlayerPrefs.GetInt("BestScore", 0) + "\nJump to run";.
  2. ב־Update, לחיצה על Space או W כאשר !running && !over מגדירה את running = true ומציגה הודעה ריקה; לאחר מכן if (!running) return;.
  3. התחל את GameOver עם if (!running) return; ועם running = false;.
  4. ב־Runner, קרא את המקשים ובדוק את הטריגרים רק כאשר game.running.

לחץ על "שחק": מסך הפתיחה ימתין עד שתקפוץ. לאחר מכן לחץ על "בדיקה".

נסו בעצמכם

using UnityEngine;

public class Runner : MonoBehaviour
{
    public float laneWidth = 2.5f;
    public float laneSpeed = 16f;
    public float jumpHeight = 1.6f;
    public float gravity = -40f;
    public float slideTime = 0.7f;
    public float magnetTime = 8f;

    public int lane;
    public float magnet;
    public bool shield;

    private CharacterController controller;
    private GameManager game;
    private Renderer body;
    private float fallSpeed;
    private float slide;
    private Color color;

    void Start()
    {
        controller = GetComponent<CharacterController>();
        game = FindFirstObjectByType<GameManager>();
        body = GetComponent<Renderer>();
        color = body.material.color;
    }

    void Update()
    {
        if (!game.over)
        {
            if (Input.GetKeyDown(KeyCode.A) || Input.GetKeyDown(KeyCode.LeftArrow)) lane = Mathf.Max(-1, lane - 1);
            if (Input.GetKeyDown(KeyCode.D) || Input.GetKeyDown(KeyCode.RightArrow)) lane = Mathf.Min(1, lane + 1);
            bool jump = Input.GetKeyDown(KeyCode.W) || Input.GetKeyDown(KeyCode.UpArrow) || Input.GetKeyDown(KeyCode.Space);
            if (jump && controller.isGrounded)
            {
                fallSpeed = Mathf.Sqrt(jumpHeight * -2f * gravity);
                StopSlide();
            }
            if ((Input.GetKeyDown(KeyCode.S) || Input.GetKeyDown(KeyCode.DownArrow)) && controller.isGrounded)
            {
                slide = slideTime;
                Resize(0.5f);
            }
        }

        if (slide > 0f)
        {
            slide -= Time.deltaTime;
            if (slide <= 0f) StopSlide();
        }
        if (magnet > 0f) magnet -= Time.deltaTime;

        if (controller.isGrounded && fallSpeed < 0f) fallSpeed = -2f;
        fallSpeed += gravity * Time.deltaTime;

        float targetX = lane * laneWidth;
        float x = Mathf.MoveTowards(transform.position.x, targetX, laneSpeed * Time.deltaTime);
        Vector3 move = new Vector3(x - transform.position.x, fallSpeed * Time.deltaTime, 0f);
        controller.Move(move);

        body.material.color = shield ? new Color(0.3f, 0.9f, 1f) : color;
        ShowPower();
    }

    void StopSlide()
    {
        if (transform.localScale.y < 1f) Resize(1f);
        slide = 0f;
    }

    void Resize(float height)
    {
        controller.enabled = false;
        transform.position += Vector3.up * (height - transform.localScale.y);
        transform.localScale = new Vector3(1f, height, 1f);
        controller.enabled = true;
    }

    void ShowPower()
    {
        string text = "";
        if (magnet > 0f) text = "Magnet " + Mathf.CeilToInt(magnet);
        if (shield) text += (text == "" ? "" : "   ") + "Shield";
        game.powerText.text = text == "" ? " " : text;
    }

    void OnTriggerEnter(Collider other)
    {
        if (game.over) return;
        if (other.CompareTag("Obstacle"))
        {
            if (shield)
            {
                shield = false;
                Destroy(other.gameObject);
                return;
            }
            game.GameOver();
        }
        else if (other.CompareTag("Coin"))
        {
            game.AddCoin();
            Destroy(other.gameObject);
        }
        else if (other.CompareTag("Magnet"))
        {
            magnet = magnetTime;
            Destroy(other.gameObject);
        }
        else if (other.CompareTag("Shield"))
        {
            shield = true;
            Destroy(other.gameObject);
        }
    }
}

כל השיעורים ביחידה משחק Unity: מסלולי שמיים

תרגלו בעצמכם: Unity אונליין