STDIO
Tìm kiếm gần đây
    • Nội dung
    • QR Code
    • 0
    • Bình luận
    • Sao chép

    Hiện Thực Game Zero Với Unity - Phần 2 - Hiện Thực Gameplay

    Hướng Dẫn Hiện Thực Game Zero Với Unity. Giới thiệu và hướng dẫn xây dựng gameplay cơ bản của game.

    Rye Nguyen

    09/08/2015
    30/09/2020
    5 phút đọc
    Hiện Thực Game Zero Với Unity - Phần 2 - Hiện Thực Gameplay

    Bài viết nằm trong chuỗi Hướng Dẫn Hiện Thực Game Zero Với Unity, cung cấp kiến thức trong việc xây dựng 1 game trên Unity, đồng thời biết cách tổ chức project hiệu quả trong Unity.

    Ở phần 2 sẽ giới thiệu và hướng dẫn xây dựng gameplay cơ bản của game.

    Giới thiệu gameplay

    Gameplay của Zero khá đơn giản: Mỗi lượt chơi là 1 phép tính được biểu thị bằng hình ảnh ngẫu nhiên 4 chất của bộ bài Tây (gọi là suit). Người chơi sẽ phải tính số lượng suit có ở 2 bên, kết hợp với các toán tử (>, <, =) và quyết định nhanh chóng.

    Sau 1 khoảng thời gian ngắn, nếu trả lời đúng sẽ được chuyển sang mức độ tiếp theo với độ khó tăng dần, trả lời sai sẽ thua. Người chơi có thể cạnh tranh bằng cách chia sẻ điểm số đạt được với nhau. Với yếu tố về thời gian và các hiệu ứng, Zero là 1 trong những game thú vị thuộc thể loại endless.

    Bài viết này sẽ hướng dẫn hiện thực lại gameplay bao gồm:

    • Random phép tính.
    • Kiểm tra tính đúng sai của phép tính. 

    GameManager

    GameManager là nơi quản lý tập trung các sự kiện xảy ra trong game.

    Toàn bộ phần Gameplay sẽ được quản lý bởi script GameManager.cs. Script này sẽ được gắn vào 1 đối tượng được gọi là GameManager.

    Giao diện và cấu trúc của các GameObject trong project như sau:

    ss_1

    Các thuộc tính và phương thức cần thiết của script GameManager.cs:

    • Left, Right, Operator: lưu trữ ảnh hiển thị mô phỏng của phép tính hiện tại.
    • Calculation: lưu trữ phép tính được ngẫu nhiên sau mỗi lần trả lời đúng. Calculation là cơ sở để vẽ các đối tượng lên màn hình.
    • Hàm GenerateNextCalculation: tạo phép tính mới. Hàm sẽ được gọi khi người chơi vượt qua được 1 câu hỏi.
    • Hàm IsRightAnswer: kiểm tra tính đúng sai của phép tính. Hàm này được sử dụng trong button khi click chuột.

    Đối với các suit đại diện cho phép tính, sử dụng các container (đối tượng chứa) và thành phần Transform của container để tìm và lưu trữ các đối tượng con. Cách hiện thực như sau (dòng 23-27, GameManager.cs):

    for(int i = 0; i < 4; i++)
    {
         m_lefts[i] = m_leftContainer.transform.GetChild(i).gameObject;
         m_rights[i] = m_rightContainer.transform.GetChild(i).gameObject;
    }

    Random phép tính

    Việc random phép tính phụ thuộc vào số lượng suit mỗi bên và số lượng các toán tử. Đối với Zero, số lượng tối đa ở 1 phía là 4, đồng thời sử dụng 3 toán tử >, <=.

    Hiện thực hàm GenerateNextCalcultion như sau (dòng 55-65, GameManager.cs):

    public void GenerateNextCalculation()
    {
    	m_calculation[0] = Random.Range(1, 5);     // Suits left
    	m_calculation[1] = Random.Range(1, 5);     // Suits right
    	m_calculation[2] = Random.Range(0, 3);     // Operator
    	
    	GetSuitsPosition(m_lefts, m_calculation[0]);
    	GetSuitsPosition(m_rights, m_calculation[1]);
    	
    	m_operator.GetComponent<SpriteRenderer>().sprite = m_sprOperators[m_calculation[2]];
    }

    Sau khi thực hiện ngẫu hiên phép tính, cập nhật lại các suit 2 bên bằng cách cho ẩn những suit không cần thiết, đồng thời toán tử cũng được cập nhật lại. Việc cập nhật vị trí các suits được hiện thực trong hàm GetSuitsPosition. Nguyên mẫu hàm như sau:

    void GameManager.GetSuitsPosition(GameObject[] _suits, int _count);

    Hàm nhận vào 2 giá trị là danh sách đối tượng cùng với số lượng. Thiết kế hàm như thế để sử dụng chung cho cả các suits ở 2 bên. Hiện thực hàm khá đơn giản do Zero chỉ có tối đa 4 suit mỗi bên (dòng 67-130, GameManager.cs):

    void GetSuitsPosition(GameObject[] _suits, int _count)
    {
    	switch (_count)
    	{
    		case 1:
    			_suits[0].SetActive(true);
    			_suits[1].SetActive(false);
    			_suits[2].SetActive(false);
    			_suits[3].SetActive(false);
    
    			_suits[0].transform.localPosition = Vector3.zero;
    			_suits[0].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			break;
    		case 2:
    			_suits[0].SetActive(true);
    			_suits[1].SetActive(true);
    			_suits[2].SetActive(false);
    			_suits[3].SetActive(false);
    
    			_suits[0].transform.localPosition = new Vector3(-0.6f, 0, 0);
    			_suits[0].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			_suits[1].transform.localPosition = new Vector3(0.6f, 0, 0);
    			_suits[1].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			break;
    		case 3:
    			_suits[0].SetActive(true);
    			_suits[1].SetActive(true);
    			_suits[2].SetActive(true);
    			_suits[3].SetActive(false);
    
    			_suits[0].transform.localPosition = new Vector3(-0.6f, -0.5f, 0);
    			_suits[0].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			_suits[1].transform.localPosition = new Vector3(0.6f, -0.5f, 0);
    			_suits[1].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			_suits[2].transform.localPosition = new Vector3(0, 0.5f, 0);
    			_suits[2].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			break;
    		case 4:
    			_suits[0].SetActive(true);
    			_suits[1].SetActive(true);
    			_suits[2].SetActive(true);
    			_suits[3].SetActive(true);
    
    			_suits[0].transform.localPosition = new Vector3(-0.6f, 0, 0);
    			_suits[0].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			_suits[1].transform.localPosition = new Vector3(0.6f, 0, 0);
    			_suits[1].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			_suits[2].transform.localPosition = new Vector3(0, 1.0f, 0);
    			_suits[2].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			_suits[3].transform.localPosition = new Vector3(0, -1.0f, 0);
    			_suits[3].GetComponent<SpriteRenderer>().sprite = m_sprSuits[Random.Range(0, 4)];
    
    			break;
    	}
    }
    

    Kiểm tra tính đúng sai bằng button

    2 button được hiện thực trong bài viết trước có nhiệm vụ kiểm tra tính đúng đắn của phép tính. Khi người chơi trả lời sai thì lượt chơi sẽ kết thúc. Ở bài viết trước, hiện thực đơn giản bằng cách xuất 1 chuỗi tương ứng ra màn hình Console. Chỉnh sửa script ButtonManager.cs cho phù hợp với mục tiêu của gameplay như sau (dòng 6-24, GameManager.cs):

    public void CheckAnswer()
    {
    	GameManager manager = GameObject.FindGameObjectWithTag("GameManager").GetComponent<GameManager>();
    	
    	if(gameObject.name == "BtnRight")
    	{
    		if (manager.IsRightAnswer())
    			manager.GenerateNextCalculation();
    		else
    	        Static.S_Debug("You're wrong!");
    	}
    	else
    	{
    		if (!manager.IsRightAnswer())
    			manager.GenerateNextCalculation();
    		else
    	        Static.S_Debug("You're wrong!");
    	}
    }

    Script GameManager.cs được gắn vào đối tượng GameManager có tag là “GameManager”. Do đó sử dụng hàm FindGameObjectWithTag để tìm và lấy ra scipt này.

    Tại đây là lúc hàm GenerateNextCalculation được gọi khi người chơi chọn đúng. Hàm kiểm tra tính đúng đắn của phép tính được đặt trong script GameManager.cs với thuộc tính public (dòng 132-138, GameManager.cs):

    public bool IsRightAnswer()
    {
    	return
    			(m_calculation[2] == 0 && m_calculation[0] == m_calculation[1]) ||
    			(m_calculation[2] == 1 && m_calculation[0] > m_calculation[1]) ||
    			(m_calculation[2] == 2 && m_calculation[0] < m_calculation[1]);
    }

    Ngoài ra, trong hàm Update gắn chức năng của 2 button này vào 2 phím mũi tên trái phải để tiện theo dõi trong Unity Editor (dòng 35-52, GameManager.cs):

    #if UNITY_EDITOR
    		{
    			if(Input.GetKeyDown(KeyCode.LeftArrow))
    			{
    				if (IsRightAnswer())
    					GenerateNextCalculation();
    				else
    					Static.S_Debug("You're wrong!");
    			}
    			else if (Input.GetKeyDown(KeyCode.RightArrow))
    			{
    				if (!IsRightAnswer())
    					GenerateNextCalculation();
    				else
    					Static.S_Debug("You're wrong!");
    			}
    		}
    #endif

    Download Project

    STDIO_ZeroUnity-2.

    Bài chung series

    Lập Trình Game

    Lập Trình Game

    Kiến thức, kỹ thuật, kinh nghiệm lập trình game.

    Phù hợp cho bạn

    Đề xuất

    Hiện Thực Game Zero Với Unity - Phần 5 - Âm Thanh Và Effect

    Hiện Thực Game Zero Với Unity - Phần 5 - Âm Thanh Và Effect

    Hướng Dẫn Hiện Thực Game Zero Với Unity. Hướng dẫn các hiệu ứng âm thanh ...

    Lập Trình GameCùng làm game

    11/08/2015

    Hiện Thực Game Zero Với Unity - Phần 1 - Nhận Sự Kiện Button

    Hiện Thực Game Zero Với Unity - Phần 1 - Nhận Sự Kiện Button

    Hướng Dẫn Hiện Thực Game Zero Với Unity. Thiết lập môi trường phát triển ...

    Lập Trình GameCùng làm game

    09/08/2015

    Khám phá thêm

    Hiện Thực Game Zero Với Unity - Phần 3 - Điểm Số Và Progress Timer

    Hiện Thực Game Zero Với Unity - Phần 3 - Điểm Số Và Progress Timer

    Hướng Dẫn Hiện Thực Game Zero Với Unity. Hướng dẫn cài đặt tính năng ...

    Lập Trình GameCùng làm game

    10/08/2015

    Hiện Thực Game Zero Với Unity - Phần 4 - Scene Và Popup

    Hiện Thực Game Zero Với Unity - Phần 4 - Scene Và Popup

    Hướng Dẫn Hiện Thực Game Zero Với Unity. Thiết kế hệ thống scene và ...

    Lập Trình GameCùng làm game

    10/08/2015

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 2: Hiện Thực LoadScene

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 2: Hiện Thực LoadScene

    Hướng dẫn cách để hiện thực một scene trong game, cũng như cách để ...

    Lập Trình GameCùng làm game

    01/03/2015

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 7: Hiện thực GameScene - Button

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 7: Hiện thực GameScene - Button

    Hướng dẫn gắn thêm các button vào game, và hiện thực hàm resetButton cho ...

    Lập Trình GameCùng làm game

    12/03/2015

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 9: Hiện thực GameScene - Điểm Số

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 9: Hiện thực GameScene - Điểm Số

    Hướng dẫn cách hiện thực GameScene, cách tính điểm và update điểm số lên ...

    Lập Trình GameCùng làm game

    15/03/2015

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 4: Hiện thực MainMenuScene

    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 4: Hiện thực MainMenuScene

    Hướng dẫn tạo màu nền cho background, tạo sprite gắn vào scene, tạo ...

    Lập Trình GameCùng làm game

    05/03/2015

    Hiện Thực Menu Select Level với Scroll Rect

    Hiện Thực Menu Select Level với Scroll Rect

    Hiện thực level select với thành phần Scroll Rect trong Unity.

    Lập Trình GameUnity

    08/08/2015

    STDIO
    Trang chính
    Công ty TNHH STDIO

    30, Trịnh Đình Thảo, Hòa Thạnh, Tân Phú, Hồ Chí Minh
    +84 28.36205514 - +84 942.111912
    developer@stdio.vn

    383/1 Quang Trung, Phường 10, Quận Gò Vấp, Hồ Chí Minh
    Số giấy phép ĐKKD: 0311563559 do sở Kế hoạch và Đầu Tư TPHCM cấp ngày 23/02/2012

    ©STDIO, 2013 - 2020