العنوان واللعب مجددًا
الدرس 20 من 20 في دورة لعبة Unity: مسارات السماء على Coddy.
أخيرًا، تبدأ اللعبة وتنتهي. تبدأ بشاشة عنوان تعرض الاسم وأفضل نتيجة وعبارة «اقفز للبدء». يبقى الطريق ساكنًا ولا تفعل المفاتيح شيئًا حتى يبدأ مفتاح القفز (Space أو W) الجولة.
يتطلب ذلك حالة ثانية إلى جانب over: running. ينهي GameOver الجولة، وبعد ذلك يؤدي الضغط على مفتاح القفز إلى تحميل المشهد من جديد، فيعيد كل شيء إلى حالته عند البداية:
if (over && (Input.GetKeyDown(KeyCode.Space) || Input.GetKeyDown(KeyCode.W)))
{
SceneManager.LoadScene(SceneManager.GetActiveScene().buildIndex);
}تُحفظ أفضل نتيجة في PlayerPrefs، لذا تبقى بعد إعادة التحميل.
التحدي
متوسط- في
GameManagerأضفusing UnityEngine.SceneManagement;وpublic bool running;. يضبط Start القيمةspeed = 0fورسالة العنوان. - في Update: يؤدي الضغط على Space أو W عندما لا تكون اللعبة قيد التشغيل ولم تنتهِ إلى بدء الجولة (
running = true، ورسالة فارغة)؛ ويؤدي الضغط على Space أو W بعد انتهاء اللعبة إلى تحميل المشهد مجددًا؛ وعندما لا تكون اللعبة قيد التشغيل، استخدم return. - تعيد GameOver الآن التنفيذ إذا لم تكن اللعبة قيد التشغيل، وتضبط
running = false، وتنهي الرسالة بـ"\nJump to run again". - في
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: مسارات السماء
تدرّب بنفسك: Playground لـ Unity