Các cuộc gọi chức năng theo từng khung so với nhắn tin hướng sự kiện trong thiết kế trò chơi


11

Các thiết kế trò chơi truyền thống , như tôi biết điều đó, sử dụng đa hình và chức năng ảo để cập nhật trò chơi đối tượng tiểu bang. Nói cách khác, cùng một tập hợp các hàm ảo được gọi theo các khoảng thông thường (ví dụ: mỗi khung hình) trên mọi đối tượng trong trò chơi.

Gần đây, tôi phát hiện ra rằng có một hệ thống nhắn tin hướng sự kiện khác có sẵn để cập nhật trạng thái của các đối tượng trò chơi. Ở đây, các đối tượng thường không được cập nhật trên cơ sở mỗi khung hình. Thay vào đó, một hệ thống nhắn tin sự kiện hiệu quả cao được xây dựng và các đối tượng trò chơi chỉ được cập nhật sau khi nhận được thông báo sự kiện hợp lệ.

Kiến trúc trò chơi hướng sự kiện được mô tả tốt trong: Hoàn thành mã hóa trò chơi của Mike McShaffry .

Tôi có thể vui lòng yêu cầu giúp đỡ với các câu hỏi sau đây:

  • Những lợi thế và bất lợi của cả hai phương pháp là gì?
  • Đâu là cái tốt hơn cái kia?
  • Là thiết kế trò chơi hướng sự kiện phổ quát và tốt hơn trong tất cả các lĩnh vực? Do đó, nó có được khuyến khích sử dụng ngay cả trong các nền tảng mombile không?
  • Cái nào hiệu quả hơn và cái nào khó phát triển hơn?

Để làm rõ, câu hỏi của tôi không phải là loại bỏ hoàn toàn đa hình khỏi thiết kế trò chơi. Tôi chỉ đơn giản muốn hiểu sự khác biệt và lợi ích từ việc sử dụng tin nhắn hướng sự kiện so với các cuộc gọi thông thường (theo khung) đến các chức năng ảo để cập nhật trạng thái trò chơi.


Ví dụ: Câu hỏi này gây ra một chút tranh cãi ở đây, vì vậy hãy để tôi cung cấp cho bạn ví dụ: Theo MVC, công cụ trò chơi được chia thành ba phần chính:

  1. Lớp ứng dụng (Giao tiếp phần cứng và hệ điều hành)
  2. Logic trò chơi
  3. Chế độ xem trò chơi

Trong một trò chơi đua xe, Game View chịu trách nhiệm hiển thị màn hình nhanh nhất có thể, ít nhất là 30 khung hình / giây. Chế độ xem trò chơi cũng lắng nghe ý kiến ​​của người chơi. Bây giờ điều này xảy ra:

  • Người chơi nhấn bàn đạp nhiên liệu đến 80%
  • GameView xây dựng một thông báo "Bàn đạp nhiên liệu trên xe hơi được nhấn tới 80%" và gửi nó đến Game Logic.
  • Game Logic nhận được thông báo, đánh giá, tính toán vị trí và hành vi của xe mới và tạo các thông báo sau cho GameView: "Draw Car 2 Fuel Đạp ép 80%", "Tăng tốc âm thanh trên xe 2", "Xe 2 tọa độ X, Y" .. .
  • GameView nhận được tin nhắn và xử lý chúng phù hợp

bạn đã tìm thấy ở đâu một số liên kết hoặc tài liệu tham khảo? Tôi không biết cách tiếp cận này (nhưng tôi biết mô hình thiết kế khá chung chung và tôi khuyên bạn nên sử dụng tốt các nguyên tắc định hướng đối tượng nói chung), nhưng tôi nghĩ rằng một sự kiện dựa trên sự kiện là tốt hơn .. hãy nghĩ về sự tiến hóa trong các hệ thống mạng: từ bỏ phiếu cho các cuộc gọi không đồng bộ .. nó được tối ưu hóa trong các tính toán và ở mức độ trừu tượng
nkint

Xin chào Nkint, cảm ơn bạn đã bình luận của bạn. Về cơ bản tôi muốn so sánh giao tiếp điều khiển sự kiện với các cuộc gọi đến các chức năng ảo. Tôi sẽ sửa đổi câu hỏi của tôi một chút. Btw, hãy xem liên kết này có chứa các mẫu mô tả trò chơi: gameprogrammingpotypes.com .
Bunkai.Satori

5
Có thể tôi đang bị câm, nhưng làm thế nào để bạn làm cho một hệ thống nhắn tin hoạt động mà không sử dụng đa hình? Bạn sẽ không cần một số loại lớp cơ sở (trừu tượng hay nói cách khác) để xác định giao diện người nhận sự kiện của bạn? (Chỉnh sửa: giả sử bạn không làm việc bằng ngôn ngữ với sự phản ánh đúng đắn.)
Tetrad

2
Ngoài ra, hiệu quả sẽ được gắn chặt với các chi tiết thực hiện. Tôi không nghĩ "cái nào hiệu quả hơn" là một câu hỏi có thể được trả lời ở dạng hiện tại.
Tetrad

1
Đối tượng trò chơi cần đánh dấu. Đối tượng trò chơi cần giao tiếp với nhau. Hai điều đó cả hai cần phải xảy ra. Việc đầu tiên bạn không làm với nhắn tin vì nó dư thừa (bạn có thể có một danh sách tất cả các đối tượng ở đâu đó, chỉ cần gọi updatecho họ). Thứ hai bạn có thể làm với nhắn tin vì nhiều lý do.
Tetrad

Câu trả lời:


8

Tôi là một người hoàn toàn tin tưởng vào sự cần thiết phải là mẹ của sáng chế. Tôi không thích mã hóa bất cứ điều gì trừ khi nhu cầu của nó rõ ràng và được xác định rõ. Tôi nghĩ rằng nếu bạn bắt đầu dự án của mình bằng cách thiết lập một hệ thống nhắn tin sự kiện, bạn đã làm sai. Tôi tin rằng chỉ khi bạn đã tạo và kiểm tra cơ sở hạ tầng của mình và có tất cả các phần trong dự án của bạn, các mô-đun làm việc được xác định rõ, bạn nên tập trung vào cách bạn sẽ kết nối các mô-đun này với nhau. Cố gắng thiết kế một hệ thống nhắn tin sự kiện trước khi bạn hiểu hình dạng và nhu cầu của từng mô-đun là không đúng.

Những lợi thế và bất lợi của cả hai phương pháp là gì?

Tôi nghĩ rằng một số người sẽ tranh luận rằng có những hệ thống nhắn tin tốt ngoài kia đã sẵn sàng để được cài đặt và sử dụng. Có lẽ điều này là đúng. Chắc chắn hiệu suất của một giải pháp xây dựng tùy chỉnh được thiết kế riêng cho nhu cầu của bạn sẽ lớn hơn một xe buýt tin nhắn đa năng. Câu hỏi lớn là - bạn sẽ dành bao nhiêu thời gian để xây dựng một hệ thống nhắn tin thay vì sử dụng một cái gì đó đã được xây dựng. Rõ ràng, nếu bạn có thể tìm thấy một số loại hệ thống sự kiện với chính xác bộ tính năng bạn cần, thì đó là một quyết định khá dễ dàng. Đây là lý do tại sao tôi đảm bảo rằng tôi hiểu chính xác những gì tôi cần trước khi tôi đưa ra quyết định đó.

Đâu là cái tốt hơn cái kia?

Chúng ta có thể nói về bộ nhớ và tài nguyên ở đây. Nếu bạn đang phát triển cho bất kỳ phần cứng nào có tài nguyên hạn chế, chắc chắn việc sử dụng một hệ thống sự kiện sẽ bị cắt giảm đáng kể. Thực sự, mặc dù, tôi nghĩ rằng vấn đề liên quan đến những gì bạn cần, như tôi đã đề cập là một cái gì đó mà bạn không biết cho đến khi bạn thấy tất cả các mảnh trông như thế nào. Nếu bạn có đủ kinh nghiệm xây dựng các hệ thống này mà bạn biết trước chính xác tất cả các phần sẽ trông như thế nào, thì bạn cũng có thể trả lời trước câu hỏi này. Tôi đoán bạn không có kinh nghiệm này, vì bạn sẽ không hỏi câu hỏi này nếu bạn đã làm.

Là thiết kế trò chơi hướng sự kiện phổ quát và tốt hơn trong tất cả các lĩnh vực? Do đó, nó có được khuyến khích sử dụng ngay cả trong các nền tảng di động không?

Phổ cập và tốt hơn trong tất cả các lĩnh vực? Một tuyên bố chăn đẹp như thế dễ dàng bị từ chối. Bất cứ điều gì thêm chi phí cần phải được thực hiện phần của khối lượng công việc. Nếu bạn không sử dụng các sự kiện đủ để đảm bảo chi phí thiết kế thì đó là thiết kế sai.

Cái nào hiệu quả hơn và cái nào khó phát triển hơn?

Hiệu quả phụ thuộc vào cách thức thực hiện của nó. Tôi nghĩ rằng một thiết kế truyền thống được phát triển tốt sẽ thực hiện tốt hơn một hệ thống dựa trên sự kiện vào bất kỳ ngày nào trong tuần. Điều này là do giao tiếp giữa các phần có thể được quản lý vi mô và được thực hiện siêu hiệu quả. Tất nhiên, điều này cũng khiến việc thiết kế từ quan điểm kinh nghiệm và thời gian cần thiết để hoàn thành nó trở nên khó khăn hơn và làm cho nó hiệu quả hơn. Mặt khác, nếu bạn thiếu kinh nghiệm này hoặc không có thời gian để phát triển ứng dụng tốt, thì sử dụng thiết kế dựa trên sự kiện phù hợp với nhu cầu của bạn sẽ hiệu quả hơn. Nếu bạn có nhu cầu sự kiện tùy chỉnh không dễ dàng phù hợp với cấu trúc dựa trên sự kiện, điều này có thể làm cho cấu trúc dựa trên sự kiện rất khó thiết kế - đặc biệt là để giữ cho thiết kế hiệu quả.


Xin chào Eric, cảm ơn bạn đã cho ý kiến ​​chi tiết về câu hỏi của tôi. Khi tôi đọc phản hồi của bạn và của người khác, việc triển khai các thông báo sự kiện có thể không gây ra phép màu trong việc tăng hiệu suất trò chơi nói chung. Thay vào đó nó sẽ làm phức tạp mọi thứ rất nhiều. Tôi muốn xem thêm một số câu trả lời, trước khi kết thúc câu hỏi này. Khi toàn bộ cuốn sách đề cập đến chủ đề này, nó có vẻ như là một ý tưởng tốt để xem xét. Tôi không chắc lắm, nếu quyết định sử dụng hay không sử dụng tin nhắn có thể được đưa ra ở giữa dự án. Nếu thông điệp sự kiện được sử dụng, tôi sẽ nói, thiết kế đối tượng tổng thể cũng phải được điều chỉnh.
Bunkai.Satori

Tôi không đồng ý. Nếu thiết kế đối tượng tổng thể được đóng gói tốt, nó phải đủ linh hoạt để được sử dụng trong bất kỳ loại khung nào. Tôi đã có thể trao đổi các phương thức giao tiếp trong các dự án lớn với rất ít công việc vì mỗi phần được gói gọn.
Erick Robertson

7

Tôi nghĩ rằng bạn đang so sánh táo và cam ở đây. Đa hình không được thay thế bằng tin nhắn cả. Bạn có thể muốn các sự kiện / nhắn tin kết nối các thành phần được ghép lỏng lẻo. Ví dụ. để gửi tin nhắn từ một thực thể khi xảy ra va chạm, để cập nhật điểm người chơi hoặc có thể để kích hoạt hiệu ứng âm thanh. Vì vậy, các lớp riêng lẻ này không biết các lớp khác và chỉ gửi và / hoặc xử lý tin nhắn.

Nhưng trò chơi của bạn rất có thể sẽ có một vòng cập nhật ở đâu đó và vì bạn vòng cập nhật đó, nên nó có thể dễ dàng được sử dụng để cập nhật tất cả các thực thể trò chơi cũng cần được cập nhật mọi khung hình. Điều này không ngăn bạn sử dụng tin nhắn mặc dù ...

Nếu bạn có một số loại cấu trúc nơi bạn thêm / xóa thực thể trò chơi, bạn cũng có thể đưa chúng vào vòng cập nhật thay vì gửi thông báo cập nhật tới chúng theo từng khung. Vậy tại sao không gọi cập nhật trực tiếp trên các thực thể trò chơi của bạn trong khi bạn đang sử dụng tin nhắn để kết nối các hệ thống phụ khác nhau trong trò chơi của mình? Tôi cũng thích khái niệm Tín hiệu / Khe cắm ( xem ví dụ qt ) cho các hệ thống giống như sự kiện.

Điểm mấu chốt: Không có cách tiếp cận nào tốt hơn, cũng không phải là độc quyền.


Xin chào, Bummzack. Cuối cùng, câu trả lời đầu tiên đã đến. Cảm ơn bạn vì điều đó :-) Khi tôi đề cập đến Kiến trúc hướng sự kiện, tôi muốn nói đến một hệ thống MVC với ba lớp chính: Áp dụng, GameView, GameLogic. Tất cả các giao tiếp giữa các trhee này sẽ được thực hiện thông qua tin nhắn. Điều này khác biệt đáng kể như hệ thống truyền thống với vòng lặp cập nhật. Mỗi hệ thống có kiến ​​trúc khác nhau, một số ưu điểm và nhược điểm và chúng có chi phí hiệu năng khác nhau. Do đó tôi tin rằng, người ta sẽ tốt hơn một chút trong một số lĩnh vực. Sau khi phân tích tốt, chúng ta sẽ có thể kết luận cái nào tốt hơn.
Bunkai.Satori

3
Tôi không thấy lý do tại sao điều này là khác nhau? Bạn sẽ cần một vòng lặp cập nhật ở đâu đó và có thể sẽ cập nhật Trình điều khiển nếu bạn muốn gắn bó với MVC. Sau đó, bộ điều khiển có thể nhắn tin cho mô hình và khung nhìn .. nhưng vì bộ điều khiển thường biết khung nhìn và mô hình, nó cũng có thể cập nhật chúng trực tiếp. Nhưng điều này không thay thế bất kỳ đa hình. Câu hỏi và giả định của bạn nghe có vẻ rất lý thuyết .. có thể sao lưu chúng bằng một số mã ví dụ hoặc một số tài liệu tham khảo?
bummzack

Cuốn sách được đề cập ở trên, Game Coding Complete, khuyến nghị nhắn tin sự kiện qua các cuộc gọi trực tiếp đến các phương thức ảo. Mặc dù, hệ thống nhắn tin trông phức tạp hơn, nhưng lợi thế của nó là mọi đối tượng trò chơi không cần kiểm tra thế giới trò chơi. Thế giới trò chơi được kiểm tra bằng logic trò chơi chỉ một lần, và sau đó chỉ những đối tượng được xử lý được cho là thay đổi trạng thái của chúng. Đây là một sự khác biệt, và có thể có nghĩa là tiết kiệm chi phí. Nếu bạn quyết định rằng các đối tượng trò chơi của bạn sẽ liên lạc qua tin nhắn, họ sẽ không được gọi mỗi khung - do đó hai cách tiếp cận là loại trừ lẫn nhau.
Bunkai.Satori

1
Đã bình chọn cho một câu trả lời phản ánh ý kiến ​​của Tetrad bên dưới câu hỏi ban đầu. @ Bunkai.Satori 'Thế giới trò chơi chỉ được kiểm tra một lần' là vòng lặp cập nhật, mọi thứ cần cập nhật đều có. Thông báo sự kiện có nghĩa là hiếm khi được thực hiện nhưng vẫn là những điều quan trọng trong công cụ (PlayerDied, MonsterDied, v.v.) rằng việc kiểm tra mọi khung hình trong vòng lặp Update () sẽ gây lãng phí nhưng rất có thể chúng được tạo ra bởi Cập nhật () vòng lặp chính nó.
James

1
Nếu bạn đã có Phiên bản thứ hai, hãy xem chương có tên Kiểm soát vòng lặp chính. Nó nên được đặt tên tương tự trong phiên bản thứ 3. Điều đó thực sự sẽ trả lời câu hỏi của bạn.
Ray Dey

4

Điều này bắt đầu như một bình luận cho câu trả lời của bummzack, nhưng đã lâu.

Trừ khi bạn thực sự làm cho nó không đồng bộ (gửi các sự kiện trên một luồng mới), các đối tượng của bạn vẫn nhận được bản ghi nhớ một cách đồng bộ. Giả sử bộ điều phối sự kiện của bạn sử dụng bảng băm cơ bản với danh sách được liên kết trong một ô, thứ tự sẽ là thứ tự các đối tượng được quảng cáo đến ô đó.

Hơn nữa, trừ khi bạn quyết định sử dụng các con trỏ hàm vì một số lý do, bạn vẫn đang sử dụng các lệnh gọi hàm ảo vì mỗi đối tượng nhận được thông báo phải triển khai IEventListener (hoặc bất cứ điều gì bạn gọi nó). Sự kiện là một sự trừu tượng hóa ở mức độ cao mà bạn xây dựng bằng cách sử dụng đa hình.

Sử dụng các sự kiện mà bạn thấy mình phải gọi một danh sách các phương pháp giặt ủi cho các sự kiện khác nhau trong trò chơi để đồng bộ hóa các hệ thống khác nhau trong trò chơi hoặc khi các phản ứng khác nhau của các đối tượng và hệ thống không thể xác định rõ ràng các sự kiện xảy ra hoặc bạn muốn để thêm nhiều phản ứng cho những diễn biến đã nói trong tương lai.

Chúng là một công cụ tuyệt vời, nhưng như bummzack đã nói, đừng cho rằng tính đa hình và các sự kiện giải quyết cùng một vấn đề.


Xin chào Bearcdp, cảm ơn bạn đã trả lời. Nó có ý nghĩa với tôi. Có một điều trong tâm trí tôi, đó là phiếu bầu cho các thông điệp sự kiện: giả sử, có 200 từ chối trong cảnh. Nếu bạn sử dụng các cuộc gọi chức năng trên mỗi khung hình trên tất cả các đối tượng, bạn phải kiểm tra tất cả 200 đối tượng để tìm kiếm mọi khung hình (một ví dụ; tất nhiên các khoảng thời gian cuộc gọi có thể được quản lý.) Với nhắn tin sự kiện, gamewworld chỉ được kiểm tra một lần. Nếu có 5 va chạm, chỉ có 5 đối tượng được thông báo bằng tin nhắn về sự kiện va chạm, thay vì 200 thử nghiệm phát hiện va chạm với các cuộc gọi trên mỗi khung. Ý kiến ​​của bạn là gì?
Bunkai.Satori

2
kiểm tra thế giới game ?? điều đó nghĩa là gì? Nó có nghĩa là phải chạy cùng 200 kiểm tra để cô lập 5 kiểm tra mà nó cần để gửi tin nhắn. Với khái niệm chức năng ảo, thế giới trò chơi chỉ được kiểm tra một lần (lần lượt từng chức năng của đối tượng), và sau đó chuyển sang chỉ 5 cần thay đổi trạng thái ... mà không cần hệ thống nhắn tin.
Steve H

1
Nghe Steve H, thế giới không va chạm. Tôi chủ yếu sử dụng các sự kiện cho các sự kiện cấp cao, chẳng hạn như PlayerJump, EnemyHit. Để xử lý hiệu quả kiểm tra va chạm, bạn cần chọn cấu trúc dữ liệu để sắp xếp vị trí vật lý của các đối tượng trong trò chơi để bạn có thể ưu tiên các đối tượng cần và không cần kiểm tra va chạm. Khi bạn đã xác định tất cả các cặp đối tượng đã va chạm, sau đó bạn có thể gửi một sự kiện với dữ liệu va chạm có liên quan (hai đối tượng, dữ liệu vận tốc / vị trí / quy tắc, v.v.).
michael.bartnett

Xin chào Steve và Beardcp, cảm ơn ý kiến ​​của bạn. Những gì bạn viết có ý nghĩa. Có vẻ như có thể có nhiều triển khai hệ thống nhắn tin sự kiện. Có thể có sự thay thế hoàn toàn của khái niệm chức năng ảo trên mỗi khung, như cuốn sách được đề cập ở trên đã nói như vậy. Tuy nhiên, hệ thống nhắn tin cũng có thể cùng tồn tại với khái niệm chức năng ảo trên mỗi khung hình, như bạn nói.
Bunkai.Satori

Tại sao bạn nói "vì một số lý do" liên quan đến con trỏ hàm? Đó là cách tôi triển khai một hệ thống sự kiện nhiều lần tôi đã viết từ đầu (Tôi làm việc bằng các ngôn ngữ có chức năng hạng nhất nhưng đó là ý tưởng tương tự; chuyển chức năng cho đối tượng trung tâm sự kiện và đối tượng đó ánh xạ các chức năng của người nghe sự kiện) vì vậy tôi tự hỏi nếu có bất lợi cho phương pháp đó.
jhocking

2

Tôi sẽ nói rằng chọn cái này hay cái kia là khá sai. Một số đối tượng cần gọi mọi khung hình - một số thì không. Nếu bạn có một đối tượng bạn muốn kết xuất, bạn cần thực hiện một cuộc gọi kết xuất tới nó mỗi khung hình. Sự kiện không thể thay đổi. Điều này cũng đúng với mọi đối tượng vật lý dựa trên thời gian - bạn phải gọi chúng là mọi khung.

Tuy nhiên, tôi không thực hiện cuộc gọi mỗi khung hình tới các đối tượng quản lý đối tượng hoặc đối tượng nhập người dùng của tôi hoặc bất cứ điều gì tương tự. Cuộc gọi ảo hàng loạt đến mọi đối tượng trên khung là một ý tưởng khủng khiếp.

Thiết kế được sử dụng cho bất kỳ đối tượng cụ thể nào phải dựa trên nhu cầu của các đối tượng đó và không dựa trên một số ý thức hệ cho toàn bộ hệ thống.

Chỉnh sửa để rõ ràng hơn trong câu đầu tiên của tôi.


Xin chào DeadMG, hãy để tôi giải thích: Trong trường hợp đã đề cập ở trên, thiết kế được chia thành ba phần chính: Lớp ứng dụng (truy cập phần cứng), Logic Logic, Chế độ xem trò chơi. Những gì được hiển thị trên cơ sở khung là Chế độ xem trò chơi. Tuy nhiên, khi Chế độ xem trò chơi ghi lại một đầu vào của người dùng (ví dụ: nhấn bàn đạp phanh trong trò chơi đuổi theo), nó sẽ gửi một thông báo "Xe 2 phanh được nhấn" đến Logic Logic để xử lý. Game Logic đánh giá hành động này, tính toán hành vi của xe và gửi tin nhắn đến Chế độ xem trò chơi: "Lốp xe 2 khối", "Xe 2 di chuyển đến X, Y". Bằng cách này, không cần thiết phải kiểm tra trên mỗi khung, nếu nhấn phanh trên mỗi chiếc xe.
Bunkai.Satori

@Bunkai: Vì vậy, bạn có một số thiết kế hướng sự kiện và một số thiết kế được gọi là mỗi khung. Điều đó khá nhiều đồng ý với câu trả lời của tôi.
DeadMG

Tôi rất vui khi tìm thấy sự hiểu biết với bạn, vì câu hỏi này đã gây tranh cãi một chút ở đây ngày hôm nay :-)
Bunkai.Satori
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.