Menu
CoddyTech

Nhanh hơn nữa

Bài học 13 trên 14 trong khóa học Game Unity: rắn 3D của Coddy.

Snake càng dài thì càng khó: mỗi lần ăn thức ăn, thời gian mỗi nhịp lại ngắn hơn một chút, nên rắn di chuyển nhanh hơn. Mức sàn giúp trò chơi vẫn có thể chơi được: đó là thời gian mỗi nhịp ngắn nhất mà trò chơi có thể đạt đến.

Mathf.Max trả về số lớn hơn trong hai số, nhờ đó tạo ra một mức sàn: Mathf.Max(value, floor) không bao giờ nhỏ hơn floor. Một trụ súng bắn nhanh hơn sau mỗi lần nâng cấp, nhưng không bao giờ bắn thường xuyên hơn mức mỗi 0.2 giây:

cooldown = Mathf.Max(cooldown - 0.05f, 0.2f);

Mathf.Min thì ngược lại, tạo ra một mức trần. Rất dễ nhầm lẫn hai hàm này: nếu dùng Min, thời gian hồi chiêu ở trên sẽ giảm xuống còn 0.2 ngay từ lần nâng cấp đầu tiên. Bộ đếm thời gian trong Update() đọc tick ở mỗi khung hình, nên thời gian mỗi nhịp ngắn hơn sẽ có hiệu lực từ bước tiếp theo.

challenge icon

Thử thách

Khó

Con rắn tăng tốc khi ăn.

  1. Trong Snake, thêm public float speedUp = 0.005f; và public float minTick = 0.08f;
  2. Khi ăn thức ăn, giảm tick đi một lượng bằng speedUp, nhưng không thấp hơn minTick: tick = Mathf.Max(tick - speedUp, minTick);

Nhấn Chơi rồi cho rắn ăn: mỗi lần, rắn sẽ di chuyển nhanh hơn một chút. Sau đó, nhấn Kiểm tra.

Tự làm thử

using System.Collections.Generic;
using UnityEngine;
using UnityEngine.InputSystem;

public class Snake : MonoBehaviour
{
    public float tick = 0.15f;   // Số giây giữa hai bước di chuyển
    public int edge = 7;         // Các ô trên bảng trải từ -edge đến edge
    public bool alive = true;
    public List<Transform> tail = new List<Transform>();
    public Transform segmentPrefab;
    private float timer;
    private Vector3 direction = Vector3.right;       // Hướng đầu rắn di chuyển ở bước trước
    private Vector3 nextDirection = Vector3.right;   // Hướng rẽ chờ đến bước tiếp theo

    void Update()
    {
        if (!alive) return;

        Keyboard keyboard = Keyboard.current;
        if (keyboard != null)
        {
            if (keyboard.upArrowKey.wasPressedThisFrame || keyboard.wKey.wasPressedThisFrame) Turn(Vector3.forward);
            if (keyboard.downArrowKey.wasPressedThisFrame || keyboard.sKey.wasPressedThisFrame) Turn(Vector3.back);
            if (keyboard.leftArrowKey.wasPressedThisFrame || keyboard.aKey.wasPressedThisFrame) Turn(Vector3.left);
            if (keyboard.rightArrowKey.wasPressedThisFrame || keyboard.dKey.wasPressedThisFrame) Turn(Vector3.right);
        }

        timer += Time.deltaTime;
        if (timer >= tick)
        {
            timer -= tick;
            Step();
        }
    }

    void Turn(Vector3 newDirection)
    {
        if (newDirection != -direction)
        {
            nextDirection = newDirection;
        }
    }

    void Step()
    {
        direction = nextDirection;
        Vector3 next = transform.position + direction;
        if (Mathf.Abs(next.x) > edge || Mathf.Abs(next.z) > edge)
        {
            Die();
            return;
        }

        for (int i = 0; i < tail.Count - 1; i++)
        {
            if (tail[i].position == next)
            {
                Die();
                return;
            }
        }

        Vector3 tailEnd = tail.Count > 0 ? tail[tail.Count - 1].position : transform.position;
        for (int i = tail.Count - 1; i > 0; i--)
        {
            tail[i].position = tail[i - 1].position;
        }
        if (tail.Count > 0)
        {
            tail[0].position = transform.position;
        }
        transform.position = next;

        if (GameManager.Instance.IsFood(next))
        {
            tail.Add(Instantiate(segmentPrefab, tailEnd, Quaternion.identity));
            GameManager.Instance.Eat();
        }
    }

    public bool Occupies(Vector3 cell)
    {
        if (transform.position == cell) return true;
        foreach (Transform segment in tail)
        {
            if (segment.position == cell) return true;
        }
        return false;
    }

    void Die()
    {
        alive = false;
        GameManager.Instance.GameOver();
    }
}

Tất cả bài học trong Game Unity: rắn 3D

Tự luyện tập: Playground Unity