Trạng thái trò chơi và xử lý đầu vào trong các hệ thống thực thể dựa trên thành phần


16

Câu hỏi của tôi là:

Làm cách nào tôi có thể xử lý các trạng thái trò chơi trong hệ thống thực thể của mình mà không cần phải giữ một chồng các đối tượng trạng thái trò chơi xung quanh?

Vì vậy, thiết kế hệ thống thực thể của tôi có nghĩa là khi một thực thể cần đăng ký cho các sự kiện đầu vào, thành phần đầu vào gọi hệ thống đầu vào và nói "đăng ký thực thể này cho đầu vào này". Đây là tất cả tốt và tốt, tuy nhiên nếu bạn thêm vào khái niệm trạng thái trò chơi này (giả sử màn hình tạm dừng), nó sẽ trở thành một vấn đề để giải quyết nếu một thực thể ở trạng thái hiện tại và sẽ nhận được đầu vào.

Tôi có thể tăng thành phần / hệ thống đầu vào để thông báo: "đăng ký thực thể này cho đầu vào này trong khi ở các trạng thái trò chơi này", nhưng điều này đòi hỏi mọi thực thể đều biết nó sẽ được sử dụng ở trạng thái nào và điều đó có thể không rõ ràng. Ngoài ra, việc giữ một danh sách các trạng thái trò chơi xung quanh mỗi đầu vào đã đăng ký (và các hệ thống khác sử dụng hàm gọi lại) có vẻ không hiệu quả lắm.

Một ý tưởng khác mà tôi có là vì sẽ có một thực thể đại diện cho trạng thái trò chơi, đánh dấu là bị vô hiệu hóa, sau đó khi tạo sự kiện đầu vào kiểm tra xem thực thể đó không phải là hậu duệ của thực thể trạng thái trò chơi bị vô hiệu hóa. Có vẻ tốn kém để làm việc cho cha mẹ cho mỗi cuộc gọi lại.

Một ý tưởng khác là để tất cả các hệ thống lưu trữ dữ liệu của chúng được khóa theo trạng thái hiện tại, theo cách đó khi tạo đầu vào, thực thể đích thậm chí sẽ không phải là một ứng cử viên. Tuy nhiên, điều này thực sự làm tổn thương khả năng cho phép liên lạc giữa các thực thể ở các trạng thái khác nhau (không phải là vấn đề quá lớn đối với màn hình tạm dừng, nhưng hãy nghĩ rằng việc chọn khóa trong Oblivion / Skyrim).

Ý tưởng khác duy nhất tôi có là để tất cả các thành phần xử lý một sự kiện thay đổi trạng thái và liên lạc với hệ thống có liên quan của chúng để vô hiệu hóa bất cứ thứ gì chúng đã đăng ký và kích hoạt lại khi chuyển về trạng thái này.

Thứ hai (đánh dấu một đối tượng là vô hiệu hóa) trở đi (có từng thành phần đối phó với thay đổi trạng thái) có vẻ như là ý tưởng tốt nhất của tôi, nhưng không ai trong số chúng nhảy ra khỏi tôi là đặc biệt tuyệt vời.

Có ai khác có bất kỳ ý tưởng khác về cách làm điều này?

chỉnh sửa Trong khi tôi nói về đầu vào cụ thể trong câu hỏi này, nó có thể có nghĩa là bất kỳ hệ thống nào có khả năng gửi tin nhắn / sự kiện đến các thực thể, chẳng hạn như va chạm, sự kiện hẹn giờ, v.v ...


6
Tôi làm như thế này: Tôi có Màn hình, MenuScreen PauseScreen GameScreen, mỗi màn hình có thể tạo Thế giới riêng (thùng chứa cho các Thực thể) và các hệ thống (như RenderingSystem) và sau đó trong GameScreen tôi tạo Thế giới, Thực thể với CameraComponent và đặt CameraComponent.RenderTarget màn hình nền. Bằng cách này, tôi có thể thêm InventoryScreen sẽ có các thực thể và hệ thống riêng (như trình kết xuất được đơn giản hóa). Đầu vào có thể được truyền từ màn hình sang thế giới, vì vậy giao diện người dùng của bạn sẽ quyết định xem nó có chuyển đầu vào sang màn hình không (nếu nó tập trung, hiển thị, v.v.) và điều đó sẽ chuyển đầu vào cho thế giới và các thực thể
Kikaimaru


2
@ Byte56 Không thực sự, chỉ có người đầu tiên phải làm với các game thủ (2 người còn lại là các quốc gia trong các thực thể) và điều đó không thực sự giải quyết vấn đề tương tự mà tôi gặp phải. Khi trò chơi ở trạng thái tạm dừng, phải có một cái gì đó xảy ra với hệ thống đầu vào để ngăn chặn nó gửi tin nhắn chuyển động đến thực thể người chơi (ví dụ), tôi không thể tìm ra cách tốt để làm điều này.
elFarto

1
OK, xem xét chúng liên quan sau đó. Câu hỏi hay.
MichaelHouse

1
Một cái gì đó khác để xem xét đã gây phiền toái cho các hệ thống dựa trên thành phần của tôi trong quá khứ: UI nhiều lớp. Hộp thoại xuất hiện trên màn hình hàng đầu thế giới hoặc đa cấp. Nó đã xuất hiện cho đến nay trong mọi trò chơi tôi đã thực hiện vì vậy tôi nói rằng hãy chắc chắn xem xét một phương pháp có thể giải quyết vấn đề đó.
ADB

Câu trả lời:


14

Những gì thường được sử dụng là một trung gian Intent Systemtrừu tượng hóa đầu vào và theo dõi bối cảnh và các trò chơi có liên quan.

Hệ thống Intent sẽ dừng truyền các đầu vào khi quá trình mô phỏng bị tạm dừng. Nó cũng xử lý ánh xạ giữa các sự kiện và ý định của bộ điều khiển (di chuyển theo hướng, chạy, bắn, tải lại ...).

Bằng cách này, những người đề nghị khác của bạn không phụ thuộc vào gamepad / đầu vào cụ thể (BUTTON_A, BUTTON_B so với BUTTON_X, BUTTON_O ...) nhưng tất cả đều phản ứng với cùng một ý định (IntentRun, IntentReload ...).

Một ưu điểm khác là hệ thống ý định có thể nhận biết các bộ điều khiển có sẵn được thêm / xóa, vì nó có thể gửi ý định đến bất kỳ thuê bao nào ngay cả ngoài mô phỏng mà bạn có thể xử lý ý định như thế nào AddPlayer(controllerID).

Bao nhiêu thông tin về trạng thái trò chơi bạn cung cấp cho hệ thống thông qua các sự kiện / tin nhắn hoặc trực tiếp là tùy thuộc vào bạn. Nhưng thời gian đầu tư vào hệ thống Ý định thường đáng giá.

Bạn có thể quản lý các bối cảnh ý định sẽ tạo ra các ý định khi chúng được gắn vào hệ thống.

Bối cảnh có thể được ưu tiên, tức là:

  • SimulationAv AvailableContext gửi ý định đến mô phỏng trong khi nó khả dụng (nhưng không chạy), ví dụ như di chuyển máy ảnh, phóng to thu nhỏ, thêm / xóa trình phát ...
  • SimulationRastyContext gửi ý định đến mô phỏng trong khi nó không bị tạm dừng trình phát di chuyển, gửi đơn vị đến vị trí, bắn ...

Bằng cách này, bạn có thể thêm và xóa các bối cảnh hiện có liên quan.

Và một điều về toàn bộ hệ thống ý định là nó sẽ chạy trong khi quá trình mô phỏng bị tạm dừng.

Một cách thường được sử dụng để chơi / tạm dừng mô phỏng trò chơi mà không phá vỡ các cập nhật không liên quan đến mô phỏng là sử dụng một bộ thời gian khác nhau. tức GenericSystem::onTime(Long time, Long deltaTime, Long simTime, Long simDeltaTime).

Với cách tiếp cận này, công cụ của bạn có thể chỉ cần chặn các mức tăng trên simTime của trò chơi, lần lượt sẽ chặn các cập nhật trên các công cụ hoạt hình & vật lý có liên quan sử dụng simTime and simDeltaTimetrong khi cho phép cập nhật liên tục hiệu ứng lò xo của máy ảnh nếu nó phải di chuyển ngay cả khi tạm dừng, hoạt hình của hiệu ứng tải trên bảng quảng cáo ảo trong trò chơi trong khi dữ liệu đang được tải xuống ...


Tôi thích thực tế rằng điều này không phải gọi một loạt các chức năng "Thay đổi trạng thái" trên tất cả các thực thể. Bạn phải lo lắng về những ý định sai được gửi không đúng lúc, nhưng tôi nghĩ điều đó tốt hơn so với giải pháp thay thế.
Thomas Marnell

các thực thể của bạn có thể bỏ qua các ý định như Nhảy trong khi trạng thái của chúng không cho phép chúng nhảy (tức là không chạm đất). nhưng họ không phải lo lắng về việc nhận được ý định như vậy trong khi trò chơi bị tạm dừng.
Chó sói

Tôi đã nghĩ đến việc để cho thực thể nói với hệ thống đầu vào những trạng thái nào để gửi tin nhắn, nhưng tôi đã không nghĩ đến việc đưa các trạng thái vào chính đầu vào, đó là một ý tưởng tốt. Ngoài ra, việc tách thời gian và simTime cách nhau cũng tốt.
elFarto

Bạn nên tránh làm đầy trạng thái liên quan đến mô phỏng của bạn với những thứ không liên quan đến mô phỏng. Di chuyển tất cả giao diện người dùng và mã liên quan đến trình phát càng xa càng tốt từ chính mô phỏng và trong mô phỏng chỉ tập trung vào các ý định.
Coyote

Này @Coyote, hệ thống này nghe rất thú vị. Bạn có thể cung cấp thêm một số thông tin bằng cách trả lời câu hỏi này ? Cảm ơn!
pek

2

Làm thế nào về việc tạo một hệ thống sự kiện toàn cầu và sau đó có một thành phần lắng nghe sự kiện cho mỗi thực thể của bạn? Sau một sự kiện "Thay đổi trạng thái trò chơi", bạn có thể sử dụng từng bộ phận cho từng thực thể cụ thể.

Giả sử bạn có một thành phần đầu vào. Sau khi thành phần người nghe sự kiện nhận được sự kiện thay đổi trạng thái trò chơi, nó sẽ thay đổi các giá trị rất cụ thể cho thành phần đầu vào cụ thể đó, do đó, nó sẽ không nhận được bất kỳ cuộc gọi đầu vào nào hoặc sẽ không thực hiện bất kỳ cuộc gọi chuyển động hoặc phản hồi nào cho chủ sở hữu hệ thống.

Điều này làm việc cho tôi vì hầu hết các thành phần của tôi được viết kịch bản (thông qua Lua). Tức là tôi có một thành phần đầu vào, được kích hoạt một lần khi nhấn phím và nó kích hoạt chuyển động + hướng và sau đó nó được kích hoạt khi phím được giải phóng và nó kích hoạt hướng dừng +. Ngoài ra còn có một thành phần lắng nghe sự kiện liên lạc với thành phần đầu vào (nếu trò chơi bị tạm dừng) để ngừng thực hiện bất kỳ chức năng nào và ngừng hoạt động nếu cần thiết. Sau đó tôi có thể dễ dàng thêm một thực thể khác có phản ứng khác với cùng các sự kiện và nhấn phím bằng cách sử dụng tập lệnh khác. Bằng cách này, bạn sẽ lưu được sự tương tác giữa các thực thể khác nhau ở các trạng thái khác nhau và thậm chí làm cho nó có thể tùy chỉnh nhiều hơn. Hơn nữa, một số thực thể thậm chí có thể không có thành phần trình nghe sự kiện trong đó.

Những gì tôi vừa giải thích về cơ bản là một ví dụ thực tế về giải pháp thứ tư của bạn.

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.