Danh hiệu: Administration
Nhóm: Guests
Gia nhập: 20-08-2014(UTC) Bài viết: 60
Cảm ơn: 2 lần Được cảm ơn: 2 lần trong 2 bài viết
|
Lập trình game Pikachu với Unity – Bài 2: Khởi tạo ma trận pikachu đúng với mọi kích thước màn hình Hôm này mình sẽ tiếp tục với bài 2, ai chưa xem bài 1 thì phải làm trước các bước của bài 1 nhé. Link bài 1: http://unityviet.com/lap...bai-1-chuan-bi-resource/
Ở bài trước ta đã có Thư mục Resource chứa prefap “item”. Công việc của bài này là dựa vào prefap này ta sẽ tạo lên tất cả các hình pikachu trong từng màn chơi
Bước 1: Tạo đối tượng quản lí cho màn chơi: Tạo thư mục tên Scripts và tạo 1 file class C#, mình đặt tên là Map.cs
Sau khi tạo được class Map, Nắm Kéo file class này vào đối tượng map, nghĩa là mình mún class này được điều khiển và sử dụng đối tương Map
Khi kéo xong, bạn kiểm tra lại bằng cách kick vào đối đượng Map. Nhìn qua cửa sổ Inspector, bạn sẽ thấy như thế này là đúng
Bước 2: Tiến hành code phần load prefap đã tạo vào game. chú ý: Bạn nên đưa tạo độ của đối tượng Map về gốc tạo độ và scale = vector đơn vị và nên xóa hết đối tượng con của Map.
Kick đúp vào file Map.cs, để mở IDE lên, mặc định sẽ mở Monobehaviour, nhưng mình quen code bên VS nên mình sẽ dùng VS File Map.cs mặc định sẽ như thế này:
2.1: Khởi tạo: Ta cần phải tạo một biến Object để lưu trữ vùng nhớ của prefap item, dùng biến này ta có thể tạo ra nhiều đối tượng khác tương đương trong game. Đồng thời ta phải load đối tượng từ prefap được tạo ở Bài 1, Unity cung cấp sẵn cho ta hàm Start để chuyên làm lúc khởi tạo game. Cũng như hàm Init() mặc định bên C#
Object prefap_pikachu;
void Start () { prefap_pikachu = Resources.Load("item"); }
2.2: Xây dựng hàm tạo ra đối tượng pikachu Như ở trên ta mới chỉ load đối tượng prefap, ( nói thếm: prefap chỉ là lưu trữ vùng nhớ, chứ tạo ra như vậy thì trong game vẫn chưa hề tồn tại đối tượng pikachu, ta phải tạo ra biến “GameObject”, biến này sẽ sử dụng vùng nhớ trên để vẽ trong game. => Như vậy ta có thể dùng 1 vùng nhớ để vẽ nhiều đối tượng ở nhiều tọa độ khác nhau => tiết kiệm bộ nhớ)
Hàm tạo ra 1 đối tượng pikachu mới và đưa nó vào 1 vị trí xác định
void AddPikachu(int type,Vector3 pos,int width,int height) { GameObject g = Instantiate(prefap_pikachu) as GameObject; g.transform.parent = this.transform; g.transform.position = pos; Sprite sprite = Resources.Load("Images/item/item"+type, typeof(Sprite)) as Sprite; g.GetComponent<SpriteRenderer>().sprite = sprite; g.transform.localScale = new Vector3(Mathf.Abs(width * 1.0f / sprite.bounds.size.x), Mathf.Abs (- height * 1.0f / sprite.bounds.size.y), 1); }
//Cực kì chú ý: Hàm AddPikachu không phải đơn giản như vậy, Lúc sau ta cần phải thêm code để mỗi lần tạo pikachu mới, ta phải đưa chỉ số đó vào ma trận điểm ảnh
2.3: Xây dựng ma trận lưu trữ thông tin trạng thái game. Như ta đã biết, pikachu là game cần được lưu trữ trạng thái các nút pikachu trên mảng 2 chiều. để ta còn biết ở vị trí nào thì đang có conpikachu nào hoặc con nào đã mất rồi và con nào vẫn còn ở đó.
Khái niệm: – Game mình sẽ có kích thước 13×8 – mảng cần thiết phải là mảng int có size là 13×8 – Mình có tất cả 36 loại pikachu, được đánh số từ 0 đến 35, Khi pikachu bị ăn/chết thì giá trị này sẽ được gán thành -1 – Quan trọng: Để dễ dàng trong sử lí tìm đường đi giữa 2 pikachu, ta cần phải khai bảo mảng dư ra 2 dòng và 2 cột. Được thêm ở đầu và cuối, Nghĩa là mảng ta cần khai báo phải là 15×10. ( khi đến phần viết code tìm đường đi từ 2 pikachu bạn sẽ hiểu vì sao nên khai báo thêm). – Như vậy, cột 0 và cột 14 sẽ vô nghĩa trong gameplay – Như vậy, dòng 0 và dòng 9 sẽ vô nghĩa trong gameplay
P/s: Bạn nên có class mới tên là Vec2 để dễ lưu trữ biến 2 biến nguyên:
using UnityEngine; using System.Collections; public class Vec2 { public int R; public int C; public Vec2() { R = 0; C = 0; } public Vec2(int r,int c) { R = r; C = c; } public Vec2(Vector2 vec) { R = (int)vec.y; C = (int)vec.x; } public Vec2(Vec2 vec) { R = (int)vec.R; C = (int)vec.C; } static int r, c; static public int FastDistance(Vec2 v1, Vec2 v2) { r = Mathf.Abs (v1.R - v2.R); c = Mathf.Abs (v1.C - v2.C); if(r>c) return r; return c; } public string Print() { string r = "(" + R + "," + C + ")"; return r; } }
Khai báo: int ROW, COL; public int[][] MAP; //ma tran pikachu public bool[][] SHIT; //dung de duyet khi dung thuat toan tim duong di , chua can quan tam public Vec2[][] SHIT_ROOT_POS; // thuật toán lun, chưa cần quan tâm public Vec2 POS1; // biến tạm, để biết con nào đang được chọn, chưa cần quan tâm public Vec2 POS2; //biến tạm, để biết con được chọn thứ 2 là ocn nào, chưa cần quan tâm public Vector3[][] POS; // ma trận, vị trí của pikachu tương ứng, để xử lí cho nhanh, ko cần phải tính lại trong gameplay public static int MIN_X; // biên lưu thông tin vị trí nhỏ nhất của mảng pikachu public static int MIN_Y; // biên lưu thông tin vị trí nhỏ nhất của mảng pikachu public static int CELL_WIDH = 28; // chiều cao mặt định của một pikachu public static int CELL_HEIGHT = 32; // chiều dai mặt định của một pikachu
Hàm khởi tạo:
{ CELL_HEIGHT = (int)(80f / (ROW - 2)); CELL_WIDH = (int)(CELL_HEIGHT * 0.8f); ROW = row; COL = col; MAP = new int[ROW][]; SHIT = new bool[ROW][]; SHIT_ROOT_POS = new Vec2[ROW][]; POS = new Vector3[ROW][]; MIN_X = -COL * CELL_WIDH / 2; MIN_Y = -(ROW ) * CELL_HEIGHT / 2; for (int i = 0; i < ROW; i++) { MAP[i] = new int[COL]; SHIT[i] = new bool[COL]; SHIT_ROOT_POS[i] = new Vec2[COL]; POS[i] = new Vector3[COL]; for (int j = 0; j < COL; j++) { SHIT[i][j] = false; MAP[i][j] = -1; SHIT_ROOT_POS[i][j] = new Vec2(); POS[i][j] = new Vector3(0, 0, 0); POS[i][j].x = MIN_X + j * CELL_WIDH + CELL_WIDH / 2; POS[i][j].y = MIN_Y + i * CELL_HEIGHT + CELL_HEIGHT / 2; POS[i][j].z = i / 10.0f; } } //PrintMap(); //RandomMap(); //CheckAndSwapThings(); }
3. Khởi tạo nhẫu nhiên ma trận. Để có thể sử dụng được các hàm trên,giả sử ta cần tạo ngẫu nhiên loại cho từng pikachu
void RandomMap() { for(int i=1;i< ROW-1;i++) { for(int j=1;j< COL-1;j++) { AddPikachu(Random.Range(0, 36), POS[i][j],CELL_WIDH,CELL_HEIGHT); } } }
Tương tự ta cần phải sửa lại code của hàm khởi tạo “Start” như sau:
void Start () { prefap_pikachu = Resources.Load("item"); if (prefap_pikachu == null) Debug.Log("123"); LMap(10, 15); RandomMap(); }
Và đây sẽ là kết quả: Bạn có thể download source code của bài này tại đây : download
Ở bài sau, sẽ đơn giản hơn, mình sẽ hướng dẫn các bạn cách tạo map nhẫu nhiên nhưng vẫn đảm bảo được game play sẽ ăn, và một số thao tác nhấn/select trong game.
|