STDIO
Tìm kiếm gần đây
    • Nội dung
    • QR Code
    • 0
    • 0
    • 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

    0 Bình luận
    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.

    Đề xuất

    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 ...
    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 ...

    Khám phá

    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 ...
    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à ...
    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 để ...
    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 ...
    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 ...
    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 ...
    Hướng Dẫn Viết Game Zero Với Cocos2d-x - Phần 5: Hiện thực GameScene - Vẽ Suit
    Hướng dẫn khởi tạo một layer mới trong game và vẽ các suit với Cocos2d-x
    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.
    Khi bạn nhấn vào liên kết sản phẩm do STDIO đề xuất và mua hàng, STDIO có thể nhận được hoa hồng. Điều này hỗ trợ STDIO tạo thêm nhiều nội dung hữu ích.. Tìm hiểu thêm.
    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