Tại một số thời điểm, một công cụ PHẢI chuyên môn hóa và biết các công cụ về trò chơi. Tôi sẽ đi vào một tiếp tuyến ở đây.
Lấy tài nguyên trong một RTS. Một trò chơi có thể có Credits
và Crystal
một trò chơi khác Metal
vàPotatoes
Bạn nên sử dụng các khái niệm OO đúng cách và đi tối đa. tái sử dụng mã. Rõ ràng là một khái niệm Resource
tồn tại ở đây.
Vì vậy, chúng tôi quyết định tài nguyên có những điều sau đây:
- Một cái móc trong vòng lặp chính để tăng / giảm bản thân
- Một cách để có được số tiền hiện tại (trả về một
int
)
- Một cách để trừ / thêm tùy ý (người chơi chuyển tài nguyên, mua hàng ....)
Lưu ý rằng khái niệm này Resource
có thể đại diện cho tiêu diệt hoặc điểm trong trò chơi! Nó không mạnh lắm.
Bây giờ hãy nghĩ về một trò chơi. Chúng ta có thể sắp xếp tiền tệ bằng cách giao dịch bằng đồng xu và thêm dấu thập phân vào đầu ra. Những gì chúng ta không thể làm là tài nguyên "tức thời". Giống như nói "phát điện lưới"
Hãy nói rằng bạn thêm một InstantResource
lớp với các phương thức tương tự. Bây giờ bạn (bắt đầu) làm ô nhiễm động cơ của bạn với tài nguyên.
Vấn đề
Hãy lấy ví dụ RTS một lần nữa. Giả sử người chơi tặng bất cứ thứ gì Crystal
cho người chơi khác. Bạn muốn làm một cái gì đó như:
if(transfer.target == engine.getPlayerId()) {
engine.hud.addIncoming("You got "+transfer.quantity+" of "+
engine.resourceDictionary.getNameOf(transfer.resourceId)+
" from "+engine.getPlayer(transfer.source).name);
}
engine.getPlayer(transfer.target).getResourceById(transfer.resourceId).add(transfer.quantity)
engine.getPlayer(transfer.source).getResourceById(transfer.resourceId).add(-transfer.quantity)
Tuy nhiên điều này thực sự khá lộn xộn. Đó là mục đích chung, nhưng lộn xộn. Mặc dù nó áp đặt resourceDictionary
điều đó có nghĩa là bây giờ tài nguyên của bạn phải có tên! VÀ nó là cho mỗi người chơi, vì vậy bạn không thể có tài nguyên nhóm nữa.
Đây là sự trừu tượng "quá nhiều" (không phải là một ví dụ tuyệt vời tôi sẽ thừa nhận) thay vào đó bạn nên nhấn vào điểm mà bạn chấp nhận rằng trò chơi của bạn có người chơi và pha lê, sau đó bạn có thể có (ví dụ)
engine.getPlayer(transfer.target).crystal().receiveDonation(transfer)
engine.getPlayer(transfer.source).crystal().sendDonation(transfer)
Với một lớp Player
và một lớp học CurrentPlayer
nơi CurrentPlayer
's crystal
đối tượng sẽ tự động hiển thị các công cụ trên HUD cho việc chuyển giao / gửi tặng.
Điều này gây ô nhiễm động cơ với pha lê, việc tặng pha lê, các thông điệp trên HUD cho người chơi hiện tại và tất cả những thứ đó. Nó nhanh hơn và dễ dàng hơn để đọc / ghi / duy trì (điều này quan trọng hơn, vì nó không nhanh hơn đáng kể)
Chú thích cuối
Trường hợp tài nguyên không xuất sắc. Tôi hy vọng bạn vẫn có thể nhìn thấy điểm mặc dù. Nếu bất cứ điều gì tôi đã chứng minh rằng "tài nguyên không thuộc về động cơ" như những gì một trò chơi cụ thể cần và những gì có thể áp dụng cho tất cả các khái niệm tài nguyên là RẤT những thứ khác nhau. Những gì bạn thường sẽ tìm thấy là 3 (hoặc 4) "lớp"
- "Lõi" - đây là định nghĩa của sách giáo khoa về động cơ, nó là một biểu đồ cảnh với các móc sự kiện, nó liên quan đến các shader và gói mạng và một khái niệm trừu tượng về người chơi
- "GameCore" - Đây là loại game khá chung chung nhưng không phải tất cả các trò chơi - ví dụ như tài nguyên trong RTS hoặc đạn dược trong FPS. Logic trò chơi bắt đầu thấm vào đây. Đây là nơi mà khái niệm tài nguyên trước đây của chúng tôi sẽ là. Chúng tôi đã thêm những điều này có ý nghĩa đối với hầu hết các tài nguyên RTS.
- "GameLogic" RẤT cụ thể cho trò chơi thực tế đang được thực hiện. Bạn sẽ tìm thấy các biến có tên như
creature
hoặc ship
hoặc squad
. Sử dụng thừa kế bạn sẽ nhận được các lớp học mà span tất cả 3 lớp (ví dụ Crystal
là một Resource
trong đó là một GameLoopEventListener
tiếng nói)
- "Tài sản" này là vô dụng đối với bất kỳ trò chơi nào khác. Lấy ví dụ các tập lệnh AI kết hợp trong nửa đời 2, chúng sẽ không được sử dụng trong RTS với cùng một công cụ.
Tạo một trò chơi mới từ một công cụ cũ
Đây là RẤT phổ biến. Giai đoạn 1 là tách ra các lớp 3 và 4 (và 2 nếu trò chơi là loại HOÀN TOÀN khác nhau) Giả sử chúng ta đang tạo RTS từ một RTS cũ. Chúng ta vẫn có tài nguyên, không phải là tinh thể và công cụ - vì vậy các lớp cơ sở trong lớp 2 và 1 vẫn có ý nghĩa, tất cả những gì tinh thể được tham chiếu trong 3 và 4 có thể bị loại bỏ. Vì vậy chúng tôi làm. Tuy nhiên, chúng tôi có thể kiểm tra nó như một tài liệu tham khảo cho những gì chúng tôi muốn làm.
Ô nhiễm ở lớp 1
Điều này có thể xảy ra. Trừu tượng và hiệu suất là kẻ thù. Ví dụ, UE4 cung cấp rất nhiều trường hợp sáng tác được tối ưu hóa (vì vậy nếu bạn muốn X và Y có ai đó đã viết mã X và Y cùng nhau rất nhanh - nó biết rằng nó đang thực hiện cả hai) và kết quả là THỰC SỰ khá lớn. Điều này không tệ nhưng nó tốn thời gian. Lớp 1 sẽ quyết định những thứ như "cách bạn truyền dữ liệu cho các shader" và cách bạn làm động mọi thứ. Làm điều đó cách tốt nhất cho dự án của bạn là LUÔN LUÔN tốt. Chỉ cần cố gắng và lập kế hoạch cho tương lai, sử dụng lại mã là bạn của bạn, kế thừa nơi nó có ý nghĩa.
Phân loại các lớp
Cuối cùng (tôi hứa) đừng quá sợ các lớp. Động cơ là một thuật ngữ cổ xưa từ ngày xưa của các đường ống chức năng cố định, nơi các động cơ hoạt động khá giống nhau về mặt đồ họa (và kết quả là có rất nhiều điểm chung), đường ống lập trình đã biến điều này trên đầu và vì thế "lớp 1" bị ô nhiễm với bất kỳ hiệu ứng nào các nhà phát triển muốn đạt được. AI là tính năng phân biệt (vì vô số cách tiếp cận) của động cơ, bây giờ nó là AI và đồ họa.
Mã của bạn không nên được nộp trong các lớp này. Ngay cả công cụ Unreal nổi tiếng cũng có NHIỀU phiên bản khác nhau cho từng trò chơi khác nhau. Có một vài tệp (khác với cấu trúc dữ liệu có thể) không thay đổi. Điều này là tốt! Nếu bạn muốn tạo một trò chơi mới từ một trò chơi khác, sẽ mất hơn 30 phút. Điều quan trọng là lập kế hoạch, để biết những gì cần sao chép và dán và những gì để lại phía sau.