Cá nhân, tôi là một fan hâm mộ của các định dạng nhị phân với các phần (như Windows PE, đơn giản hơn nhiều). Chúng cũng dễ phân tích hơn (nhưng đó chỉ là ý kiến của tôi .... Tôi đã làm việc với XML đủ để khiến tôi đau đầu, kiểm tra xem getEuityByName đã trả về một giá trị hay danh sách các giá trị ... ugh). Vì vậy, nếu tôi là bạn, tôi sẽ biến nó thành như thế này:
".MMF\0" // magic value at the start, null-terminated string. stands for My Map Format :)
char header_length // useful when parsing. char is a byte, of course, an unsigned one
char version // version of the map file. (you don't really need ints here, because you probably won't be needing more than 255 versions for example, but you can also use them)
char* map_name // null terminated string describing the name of the level/map
char* author_name // if you are going to have a map editor for the general public, it would be nice to credit the person who made the map
int width // it's probably wise to plan ahead and expect an int here when you're parsing the file
int height
".layer\0" // we begin another subsection
char header_length
char type // type of the layer. for example, you can put 1 there if you want this to be a layer describing different tiles/block in a Terraria like game
".data\0" // yet another subsection. this will hold the data for the tiles
// in a hypothetical terraria 2d game, you would lay down tiles from
// the top-right corner (0,0) and then begin writing row after row
// write(1,0); write(2,0); write(3,0); ... then write(0,1); write(1,1);
// write(2,1); write(3,1); and so on..
char t1 // tile at (0,0). for example, value 0 is empty, or passable tile
char t2 // tile at (1,0). this might be a dirt block - value 1
char t3 // tile at (2,0). a rock, perhaps? value 3
(...)
char tn // tile at (width-1, height-1) or the bottom-left tile
".layer\0" // another layer.
char header_length
char type // let this on be of value 2, and let it describe portals.
// putting portals in a game makes it instantly 20% cooler
".data\0"
char t1 // 0, no portal here at tile (0,0)
char t2 // still nothing
char t3 // nope, try again
(...)
char t47 // at some location, you made a red portal. let's put 1 here so we can read it in our engine
(...)
char t86 // looke here, another 1! you can exit here from location corresponding to t47
(...)
char t99 // value 2. hm, a green portal?
(...)
char tn // bottom-left tile, at (width-1, height-1)
".layer\0" // another layer
char header_length
char type // value 3, player&enemies spawn points
char something // you don't have to have header len fixed. you can add stuff later
// and because you were smart enough to put header length
// older versions can know where the stuff of interest lays
// i.e. version one of the parser can read only the type of layer
// in version two, you add more meta-data and the old parser
// just skips it, and goes straight to the .data section
".data\0"
char t1 // zero
char t2 // zero
char t3 // zero
(...)
char t42 // a 1 - maybe the player spawn point. 5 tiles to the right
// there's a red portal
(...)
char t77 // a 2: some enemy spawn point
(...)
char tn // last tile
,
Ưu điểm:
- Trông thật hấp dẫn.
- Làm cho bạn nghĩ rằng bạn biết một cái gì đó về lập trình, làm công cụ theo cách cũ.
- Bạn có thể tự viết các cấp của mình trong trình soạn thảo hex:
- Nói chung nhanh hơn INI và XML, cả từ quan điểm viết và đọc
- Đó thực sự là một luồng dữ liệu byte dài. Không cần phải dành thời gian để làm cho nó trông đẹp, thụt vào (như những gì bạn muốn làm với XML).
- Thật dễ dàng để thêm công cụ trong các tiêu đề. Nếu một phần dữ liệu xuất hiện ở dưới cùng của tiêu đề, các phiên bản cũ của trình phân tích cú pháp có thể được hướng dẫn để tránh nó và chuyển đến phần của tệp mà họ hiểu.
Nhược điểm:
- Bạn phải chăm sóc tốt vị trí dữ liệu.
- Các trường dữ liệu phải được đặt hàng.
- Bạn phải biết kiểu của chúng trong trình phân tích cú pháp - như tôi đã nói, nó chỉ là một chuỗi byte dài.
- Di chuyển dữ liệu theo một vị trí (ví dụ: bạn quên ghi loại lớp; trình phân tích cú pháp mong đợi một byte ở đó và nó tìm thấy giá trị của '.' - điều đó không tốt) làm rối tung toàn bộ mảng dữ liệu từ điểm đó trở đi.
- Khó nhảy ngay vào - không có API, không có chức năng như getLayerWidth () - bạn phải tự thực hiện tất cả điều đó.
- Có khả năng rất nhiều không gian lãng phí. Lấy lớp thứ ba chẳng hạn. Nó chắc chắn sẽ được đóng gói với rất nhiều số không. Điều này có thể được phá vỡ mặc dù nếu bạn sử dụng một số loại nén. Nhưng một lần nữa, điều đó lại gây rối với những thứ cấp thấp một lần nữa ...
Nhưng điều tốt nhất trong cách tiếp cận này theo ý kiến của tôi là - bạn có thể tự làm tất cả. Rất nhiều thử và sai, nhưng cuối cùng, bạn đã học được rất nhiều.