Uniform Grid trong C++

Chào anh chị !
Em có tạo một Grid để quản lý các đối tượng trong Game.

vector<Game_Object*> List_Game_Object; // danh sách đối tượng Game
struct Cell_List
{
     int Pos; // Vị trí đối tượng trong List Game Object
     int Unit_Type; // Loại đối tượng.
}

Một đối tượng của em có thể ở trong nhiều ô và một ô có thể chứa nhiều đối tượng khác nhau.
vector<Cell_List> Map[100][100];
Ban đầu khởi tạo Map thì chỉ cần đối tượng có 1 phần ở trong 1 ô là em push nó vào ô đó luôn.
Nhưng khi đối tượng di chuyển từ ô này sang ô khác thì các phần của nó cũng di chuyển theo. Do đó cần xóa đối tượng tại ô cũ và tại ô mới thêm đối tượng vào. Chỗ này em làm khá loằng ngoằng và dối dắm, mong anh chị giúp đỡ em chỗ này với ạ !
Em cám ơn.

trước tiên sửa tên Pos lại thành tên nào đó để khỏi phải comment “Vị trí đối tượng trong List Game Object” :V Ví dụ như tên là Game_Object_Index :V (em đã đặt tên có viết hoa mỗi từ rồi, cần gì _ phân cách nữa? Cách đặt tên hơi kì lạ @_@)

em xóa loằng ngoằng chỗ nào :V Nếu loằng ngoằng thì cho vào 1 hàm là hết phải dòm đống loằng ngoằng đó nữa :V

4 Likes

Sao trong CellList không tham chiếu thẳng tới GameObject luôn cho xong. Nếu chỗ đó chưa có đối tượng nào thì là NULL thôi.

NHƯNG:
Mình nghĩ cái vị trí nên là x, y (cho cột và dòng của mảng) và do GameObject sở hữu.

Mình chưa rõ trò chơi của bạn thế nào, nhưng đã có bản đồ, địa hình và đơn vị. Bản đồ chỉ quản lý địa hình (các ô) thôi, đơn vị (GameObject) thì do một bộ phận khác quản lý và định vị nó trên bản đồ. Đừng bắt bản đồ quản lý luôn đơn vị, lằng nhằng lắm!

3 Likes

Em viết tắt của Position, trong mỗi Game_Object, em cũng có một cái vector , Cell gồm hai thành phần là hàm và cột, nó là một danh sách chứa các ô mà nó ở trong, em thấy cách này hơi loằng ngoằng ở chỗ em phải lặp qua cái vector trên đối tượng một lần để biết những ô nào nó đi qua, rồi sau đó lại lặp qua những hàng và cột hiện tại nó có trong đó, sau đó kiểm tra xem cái cặp hàng cột nào cũ mà khác hiện tại thì lấy cặp hàng cột này ra, vào cái Map[hàng][cột] này để cho cái Pos=-1, tức là nó không tồn tại nữa, tổng cộng 3 vòng for lồng nhau, em thấy hơi chậm, chưa kể lại tiếp tục thêm nó vào những ô mới rồi lại thêm những ô nó đang ở vào cái vector của nó.

di chuyển GameObject obj từ (x0,y0) tới (x1,y1) tại sao lại phải kiểm tra những hàng và cột nào nữa? @_@ Remove obj ở Map[y0][x0] rồi insert obj đó vào Map[y1][x1] là xong rồi chứ? :V

3 Likes

Map em có nhiều đối tượng, mỗi đối tượng có thể ở trong nhiều ô, ví dụ Hình chữ nhật ở trong các ô (0,0), chiều dài và rộng của nó em cho đều bằng 50, 50, kích thước một ô bản đồ là 32, 32, tức là bây giờ hình chữ nhật của em ở trong 4 ô rồi, khi khởi tạo bản đồ em phải push vào 4 ô này cái hình chữ nhật này và push vào đối tượng hình chữ nhật 4 ô nó đang ở. Em phải kiểm tra hàng cột để biết được những ô nào vật thể vẫn ở đó, những ô nào vật thể đã đi ra rồi.

Về phần Uniform Grid này em tìm tài liệu tiếng việt thì không thấy có, tìm tiếng anh em mới tìm được 2 bài, một bài dùng Js, một bài dùng C++. Bài về C++ em thấy họ cũng làm như anh nói, Cell_List là một link list, nhưng em thấy cách này chỉ có hiệu quả nếu mỗi đối tượng chỉ nằm trong 1 ô. Em phải dùng bản đồ quản lý đối tượng vì em dùng A*, nó cần biết chính xác ô này có đối tượng nào không để nó đi qua.

vậy à :V Vậy thì cùng lắm remove obj khỏi 4 ô, thêm obj lại vào 4 ô mới :V

mà tại sao ko để cho 1 obj là 1 ô, cho vào nhiều ô chi :V

4 Likes

Em làm trò giống Aoe, nông dân chiếm 1 ô, cái nhà nó chiếm 9 ô, làm sao em cho nông dân to bằng ngôi nhà được. :smile:

à vậy thì ví dụ 1 quân có kích thước 2x2, em chỉ cần nhớ vị trí của 1 trong 4 ô đó là suy ra 3 ô còn lại ở vị trí nào rồi.

Ví dụ move(obj, dx, dy, map), obj có kích cỡ 2x2:

  • lấy các tọa độ của obj hiện tại: (x,y), (x+1,y), (x,y+1), (x+1,y+1)
  • tính các tọa độ di chuyển tới: (x+dx, y+dy), (x+1+dx, y+dy), (x+dx, y+1+dy), (x+1+dx, y+1+dy)
  • kiểm tra các tọa độ di chuyển tới có chướng ngại vật hay ko
  • nếu ko có thì thực hiện di chuyển tới:
    • xóa obj khỏi map[y][x], map[y][x+1], map[y+1][x], map[y+1][x+1]
    • thêm obj vào map[y+dy][x+dx], map[y+dy][x+1+dx], map[y+1+dy][x+dx], map[y+1+dy][x+1+dx]

Mỗi obj chỉ chứa vị trí x, y và kích thước w, h. Khi đó sẽ suy ra được các ô nó đang chiếm trên bản đồ là
(x,y), (x+1, y), …, (x+w-1,y)
(x,y+1), (x+1, y+1), …, (x+w-1,y+1)

(x,y+h-1), (x+1, y+h-1), …, (x+w-1,y+h-1)

chỉ cần duyệt O(w*h*x) là xong rồi, cũng 3 vòng lặp nhưng cũng lẹ vì whx (với x là số obj trong map[…][…]) gần như là hằng số :V

5 Likes

Ờ ờ ờ, làm chi nhọc thế!
Như @tntxtnt nói thôi. Mỗi đơn vị chỉ có 1 tọa độ thôi, từ đó suy ra các “mảnh ghép” khác của nó.

3 Likes

Em cám ơn anh, nhưng em muốn hỏi thêm, giả sử Đối tượng của em ở tọa độ 0,0 . Nó chiếm tất cả 9 ô. Nhưng giờ em muốn kiểm tra ô 3,3 chẳng hạn, ô này thuộc vùng của đối tượng này. Tức là lúc này nếu em muốn kiểm tra ô 3,3 có đối tượng nào không thì phải cần duyệt các ô lân cận để xem có ô nào chứa đối tượng này không, hoặc là em cần duyệt qua toàn bộ đối tượng để xem có đối tượng nào chiếm ô này hay không. Nếu đúng theo em hiểu thì em thấy cách này nếu có nhiều đối tượng thì không tối ưu cho lắm.

kiểm tra ô 3,3 có đối tượng nào ko thì em chỉ cần ktra Map[3][3].empty() hay ko là được mà? :V

“thuộc vùng” là sao :V

4 Likes

Vâng, em cám ơn anh !

83% thành viên diễn đàn không hỏi bài tập, còn bạn thì sao?