Làm cách nào để tạo các hạt phản ứng với người chơi và kẻ thù?


38

Tôi hiện đang tạo một trò chơi với công cụ trò chơi của riêng mình mà tôi đã viết bằng C ++ và tôi đang sử dụng SDK directx gần đây nhất.

Trò chơi là một game bắn súng không gian từ trên xuống (với một vòng xoắn khá thú vị) và tôi đang mong muốn có một loại hiệu ứng tinh vân mà người chơi sẽ bay qua. Tôi thực sự muốn thử và cảm nhận xúc giác tốt đẹp của hàng trăm hạt di chuyển ra khỏi con tàu của người chơi khi nó bay vào chúng. Giống như cách các hạt di chuyển ra khỏi lối chơi của người chơi trong Geomtry Wars trên XBLA.

Tôi là một lập trình viên có kinh nghiệm khi nói đến C ++. Tôi không biết, tuy nhiên, làm thế nào để bắt đầu thực hiện hiệu ứng này. Có ai có bất kỳ ý tưởng hay lựa chọn thiết kế nào mà tôi có thể muốn xem xét không? Hãy trả lời cho bất kỳ mức độ sâu bạn thích.

Câu trả lời:


65

Đó là một ý tưởng tuyệt vời. Bạn sẽ cần một số loại độ khuếch tán xung quanh tàu của bạn. Có ba mô hình vật lý tôi có thể nghĩ rằng bạn có thể muốn:

  1. Bạn muốn nó trông giống như một môi trường lỏng, trong đó cân bằng độ dốc áp suất, tức là một khi bạn đã vượt qua một số hạt chúng di chuyển trở lại vào thức của bạn (như nước phía sau thuyền). Trong trường hợp này, các vị trí của hạt là tuyệt đối và đó chỉ là mối quan hệ của chúng với người chơi tạm thời sửa đổi vị trí kết xuất của chúng . Điều này giống như khi bạn chuyền một chiếc kính lúp dày lên các vật và sự nhiễu xạ dường như làm cho chúng chuyển động - nhưng chỉ cho đến khi bạn di chuyển chiếc kính đi. Trong trường hợp này, tàu của bạn là kính.

  2. Nếu bạn muốn họ di chuyển ra khỏi tàu và tiếp tục di chuyển một khi họ đã di chuyển. Điều này giống như vật lý tiêu chuẩn trong không gian trống nói chung, nơi không có độ dốc áp suất (hoặc rất nhỏ).

  3. Bạn muốn di chuyển các hạt ra khỏi con tàu một cách nhanh chóng khi nó đến gần, như trong (1) và (2), nhưng một khi con tàu đã biến mất, các hạt sẽ từ từ tự cân bằng lại để trở nên bình đẳng khi bạn thức dậy.

Chung cho cả ba giải pháp : bạn cần có một trường khuếch tán di chuyển với tàu của bạn. Trong ví dụ này, chúng tôi sẽ làm cho nó tròn. Sau đó, bạn phát hiện vectơ, gọi nó là v1, giữa con tàu và từng hạt trong khu vực đó. Đẩy hạt của bạn đi dọc theo vector đó. Bạn sẽ đẩy nó đi mạnh đến mức nào tùy thuộc vào khoảng cách từ tàu: sử dụng 1 - v1.magnitude. Công thức này sẽ cung cấp cho bạn một cường độ tuyến tính, tuy nhiên bạn có thể sửa đổi nó để sử dụng một thứ khác như đường cong cường độ tròn làm giảm sức mạnh về phía các cạnh. Điều này sẽ mang lại cho nó nhiều hơn một cái nhìn như thể có một dải áp suất hình cầu thay vì hình tròn xung quanh con tàu.

Đối với giải pháp 1 : Tất cả những gì bạn làm bây giờ là sửa đổi vị trí kết xuất của hạt đó (nghĩa là vị trí sprite) trên mỗi bản cập nhật kết xuất , theo vectơ này. Bởi vì bạn đang làm theo cách này, đây hoàn toàn là hiệu ứng kết xuất và không ảnh hưởng đến vị trí thế giới thực của hạt. Vì vậy, bạn thêm vị trí thế giới vào phần bù kết xuất (v1) và bây giờ bạn có các hạt được dịch chuyển độc đáo khi bạn di chuyển qua hoặc bên cạnh chúng, và hoàn nguyên các hạt khi bạn đi ngang qua (phía sau bạn).

Đối với giải pháp 2 : Thay vì chỉ áp dụng v1 cho vị trí xem, hãy áp dụng nó trên mỗi bản cập nhật logic , cho vị trí của hạt. Vì vậy, p1.position += v1. Vì vậy, bạn đang áp dụng một lực gia tốc cho hạt, chuyển thành vận tốc. Có lẽ, bạn sẽ muốn tốc độ của từng hạt bị giảm xuống để chúng sẽ dần dần chậm lại và dừng lại sau khi bạn vượt qua. Bạn có thể thấy giải pháp này sẽ dẫn đến các hạt bị bó lại trong tinh vân của bạn như thế nào, bởi vì chúng sẽ không bao giờ được sử dụng lại. Không thực tế lắm, tôi chắc chắn, vì tinh vân có độ dốc áp suất bên trong chúng, cho dù thực tế có yếu đến đâu.

Đối với giải pháp 3: Giống như (2), nhưng trong trường hợp này, bạn sẽ phải xác định lại các hạt của mình. Để thực hiện điều này một cách dễ dàng là một chút cách tiếp cận vũ phu, nhưng vì đây chỉ là các hạt và do đó rất bắt mắt, nên bạn có thể không cần phải bao phủ một khu vực quan tâm lớn (có lẽ chỉ là bán kính của playerPocation + maxPlayerSpeedPerTick hoặc bất cứ điều gì diện tích hình chữ nhật bao quanh đó, cho mục đích logic). Mỗi hạt sẽ tác dụng một lực lên các hạt khác trong phạm vi quan tâm. Họ sẽ áp dụng các lực lượng dựa trên, một lần nữa, vào khoảng cách của họ với nhau. Tính toán tất cả các lực liên hạt trong một lần quét trên toàn khu vực quan tâm, và sau đó áp dụng tất cả các lực trong một lần quét. Cuối cùng, hãy chắc chắn rằng bạn chỉ thực hiện quá trình xử lý lực liên hạt này trên các hạt có vận tốc bằng không. Và một khi bất kỳ hạt nhất định đạt đến một số tốc độ tối thiểu,

Có tất cả các loại công thức khuếch tán, vv, nhưng tôi nghĩ trong trường hợp này, một giải pháp đơn giản hoạt động tốt nhất.


Mate, thật không may, hiện tại tôi không có tiếng tăm gì để nâng cao câu trả lời của bạn (và tôi chỉ có thể làm điều đó một lần, ít hơn so với nó xứng đáng). Bạn hoàn toàn đóng đinh những gì tôi đang tìm kiếm trong giải pháp đầu tiên của bạn. Câu trả lời tuyệt vời. Thành thật. Cảm ơn!
Matt McDonald

Matt rất vui, đó là một câu hỏi hay và đáng để rèn luyện trí não!
Kỹ sư

Tôi cũng đã quyết định rằng với rất ít thay đổi trong mã, tôi có thể áp dụng điều này cho các tiểu hành tinh nhỏ hơn trong vành đai. Cảm ơn một lần nữa.
Matt McDonald
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.