Oyuncuya ve düşmanlara tepki gösteren parçacıklar nasıl yaratırım?


38

Şu anda C ++ ile yazdığım kendi oyun motorumla oyun yapıyorum ve en yeni directx SDK'yı kullanıyorum.

Oyun yukarıdan aşağıya bir uzay oyunu (oldukça ilginç bir bükülme ile) ve oyuncunun içinden geçeceği bir nebula etkisine sahip olmak istiyorum. Gerçekten, oyuncu gemisinin kendilerine doğru uçarken yüzlerce parçacığın bu dokunsal hissini vermeye çalışıyorum. Parçacıklar, XBLA'daki Geomtry Savaşlarında oyuncunun yolundan nasıl çıkacağına benziyor.

C ++ konusunda deneyimli bir programcıyım. Ancak, bu etkiyi uygulamaya nasıl başlayacağımı bilmiyorum. Bakmak isteyebileceğim herhangi bir harika fikir veya tasarım seçeneği olan var mı? İstediğiniz herhangi bir derinlik derecesine cevap vermekten çekinmeyin.

Yanıtlar:


65

Güzel bir fikir. Geminizin etrafında bir çeşit yayılma gradyanına ihtiyacınız olacak. İsteyebileceğini düşünebildiğim üç fiziksel model var:

  1. Neredeyse sıvı bir ortam gibi görünmesini istersiniz, burada basınç gradyanı yeniden dengelenir, yani bazı parçacıkları geçtikten sonra tekrar uyanmanıza geri döner (teknenin arkasındaki su gibi). Bu örnekte, parçacığın konumları mutlaktır ve yalnızca oluşturma konumlarını geçici olarak değiştiren oyuncu ile olan ilişkisidir . Bu, nesnelerin üzerine kalın bir büyüteçle geçtiğinizde olduğu gibi biraz ve kırınım onların hareket etmesini sağlıyor gibi gözüküyor - ama sadece camı hareket ettirene kadar. Bu durumda, geminiz camdır.

  2. Gemiden uzaklaşmalarını ve hareket ettiklerinde hareket etmeye devam etmelerini istiyorsanız. Bu, genellikle boş alanda, (veya çok küçük) basınç gradyanlarının olmadığı standart fizik gibidir.

  3. Parçacıkları, (1) ve (2) 'de olduğu gibi, yaklaşırken hızla gemiden uzaklaştırmak istiyorsunuz, ancak gemi gittiğinde, parçacıklar, uyanıkken eşit olmaları için kendilerini yavaşça yeniden dengeleyeceklerdir.

Üç çözümde de ortak : Geminizle birlikte hareket eden bir difüzyon alanına sahip olmanız gerekir. Bu örnekte onu dairesel yapacağız. Daha sonra vektörü tespit eder, v1 olarak adlandırın, gemi ile o bölgedeki her parçacık arasında. Parçacını o vektör boyunca uzağa it. Onu ne kadar güçlü bir şekilde ittireceğiniz, gemiye olan mesafesine bağlı olacaktır: kullanın 1 - v1.magnitude. Bu formül size doğrusal bir kuvvet verecektir, ancak kenarlara doğru gücü azaltan dairesel bir kuvvet eğrisi gibi başka bir şey kullanacak şekilde değiştirebilirsiniz. Bu, gemi etrafındaki dairesel basınç gradyanından ziyade küresel bir alan varmış gibi görünmesini sağlar.

Çözüm 1 için : Tek yapmanız gereken, bu vektör tarafından her render güncellemesinde o partikülün oluşturma pozisyonunu (yani, sprite pozisyonu) değiştirmek . Çünkü bu şekilde yapıyorsunuz, bu tamamen bir görüntü oluşturma etkisidir ve parçacığın gerçek dünyadaki konumu üzerinde bir etkisi yoktur. Böylece dünya pozisyonunu render ofsetine (v1) eklediniz ve artık geçmişe kendilerine doğru ya da yanına doğru ilerlerken yerinden güzel bir şekilde yer değiştirmiş parçacıklara sahipsiniz ve geçerken (arkanızda) parçacıkları sorunsuz bir şekilde geri döndürün.

Çözüm 2 için : Sadece v1'i görünüm konumuna uygulamak yerine, her mantık güncellemesinde parçacığın konumuna uygulayın. Öyleyse p1.position += v1. Yani, parçacıklara hız yapan bir kuvvet uygulıyorsunuz. Muhtemelen, her parçacığın hızının azaltılmasını isteyeceksiniz, böylece yavaş yavaş yavaşlarlar ve geçtikten sonra dururlar. Bu çözümün nebulada biriken partiküllerle sonuçlanacağını görebilirsiniz, çünkü asla tekrar karışmazlar. Çok gerçekçi değil, eminim, çünkü bulutsuların gerçekte ne kadar zayıf olursa olsun, içinde basınç gradyanları vardır.

Çözüm 3 için: (2) ile aynı, ancak bu durumda parçacıklarınızı yeniden dağıtmanız gerekecek. Bunu kolayca yapmak biraz kaba kuvvet yaklaşımıdır, ancak bunlar sadece parçacıklar ve dolayısıyla göz şekeri oldukları için büyük bir ilgi alanı (muhtemelen sadece playerPosition + maxPlayerSpeedPerTick yarıçapı ya da her neyse) kapsamına girmeniz gerekmez. dikdörtgen alan, mantıksal amaçlarla bunu sınırlar). Her bir parçacık, ilgilenilen alan içinde diğer bir parçacık üzerinde bir kuvvet uygulayacaktır. Bir kez daha birbirlerinden olan mesafelerine dayanan kuvvetler uygulayacaklar. Tüm bölümler arası kuvvetleri, ilgilenilen alan boyunca tek bir taramada hesaplayın ve ardından tüm kuvvetleri tek bir taramada uygulayın. Son olarak, partiküller arası kuvvet işlemini yalnızca sıfır hıza sahip parçacıklar üzerinde gerçekleştirdiğinizden emin olun. Ve herhangi bir parçacık herhangi bir minimum hıza ulaştığında,

Dışarıda her türlü difüzyon formülü var, ancak bu durumda basit bir çözüm en iyi sonucu veriyor.


Mate, maalesef şu anda cevabınızı olumlu yönde etkileyecek bir üne sahip değilim (ve sadece bir kere yapabilirim, ki bu hak ettiğinden daha az). Kesinlikle ilk çözümünüzde aradığım şeyi çivilediniz. Harika cevap Dürüst. Teşekkürler!
Matt McDonald

Tamamen zevk Matt, bu iyi bir soru ve beyni esnetmeye değer!
Mühendis

Ayrıca, koddaki çok küçük bir değişiklikle bunun bir kemer içindeki daha küçük asteroitlere uygulanabileceğine karar verdim. Tekrar teşekkürler.
Matt McDonald
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.