Bir oyunda Time Stop veya Bullet Time nasıl kodlanır?


11

XNA 4.0'da tek oyunculu bir RPG platform geliştiriyorum. Zamanı "durduracak" veya yavaşlatacak bir yetenek eklemek istiyorum ve sadece oyuncu karakterinin orijinal hızında hareket etmesini istiyorum (Baldur Kapısı serisinden Time Stop büyüsüne benzer). Kesin bir uygulama değil, bazı genel fikirler ve tasarım kalıpları arıyorum.

EDIT: Mükemmel giriş için teşekkürler. Aşağıdaki çözümü buldum

    public void Update(GameTime gameTime)
        {

            GameTime newGameTime = new GameTime(gameTime.TotalGameTime,
 new TimeSpan(gameTime.ElapsedGameTime.Ticks / DESIRED_TIME_MODIFIER));
            gameTime = newGameTime;

ya da bu çizgiler boyunca bir şey. Bu şekilde oynatıcı bileşeni için farklı bir süre ve geri kalanı için farklı bir zaman ayarlayabilirim. Böyle bir çarpıtma zamanının merkezi bir unsur olacağı bir oyun için çalışmak için yeterince evrensel değildir, ancak umarım bu durumda çalışmalıdır. Biraz da ana Güncelleme döngüsünü temizlediğinden hoşlanmıyorum, ama kesinlikle onu uygulamanın en kolay yolu. Sanırım bu aslında tesselode'un önerdiği gibi, bu yüzden ona yeşil kene vereceğim :)

Yanıtlar:


8

Bu kötü bir çözüm olabilir, ancak zorunlu değildir. Delta zamanı kullanıyorsanız, belirli şeylerin hızını değiştirmek için bunu değiştirebilirsiniz.

Örneğin:

player.update(dt)
dt = dt * .5 --half speed
enemy.update(dt)

Bu, elbette, sadece düşmanı güncellediğinizde başka bir şeyden ziyade söyleyebiliyorsanız işe yarar. Ayrıca her şeye bir hız değeri verebilir ve şöyle bir şey yapabilirsiniz:

x = x + xspeed * dt * speed

İlk bölüm çok mantıklı, ikinci bölüm belli değil
AturSams

2
Değiştirebileceğiniz bir hız değişkenini hareket ettiren her nesneyi verin ve bir dönüşümünüz varsa (örneğin, x olarak), büyüklüğü speed değişkeniyle çarpın.
tesselode

Şimdi mantıklı. :)
AturSams

İkinci fikir geliyor ... kapalı. Hareketin sadece "hız" faktörü ile ölçeklendirilmesi fizik güdümlü nesneler için işe yarayabilir, ancak AI normal hızda tepki verebilir, sadece hareketleri yavaşlar / bozulur.

AI'nın normal hızda tepki verebileceği ne demek istiyorsun? Bir hız değişkeni uygulanamayan AI'nın hangi kodu olurdu?
tesselode

3

Delta zamanı kullanmak (son kareden bu yana geçen milisaniye) düşmanları yavaşlatmak için yeterli olmayabilir. Saldırı hızı gibi şeyler, son saldırı süresine göre uygulanabilir. Zamana bağlıysa hareketi yavaşlatırken, yavaş saldırı oranını, büyü dökümünü ve diğer etkileri (Sağlık rejenerasyonu, büyü etki süresi) ve benzeri şeyleri ihmal eder.

Tek oyunculu bir oyunda büyük bir oyun öğesi grubunu yavaşlatmak istiyorsanız, her yaratık için ikinci bir iç saat oluşturabilirsiniz, saat, yaratık göründüğü anda başlar. Yavaş bir büyü yapıldığında, her kare, saat gerçekte geçen sürenin% x'i kadar artırılır. Daha sonra tüm canavar davranışları kendi iç saati tarafından belirlenir. Çeşitli canavarların yavaşlamaya karşı direnci varsa, kendi saatlerini kullanabilirler, temelde çok fazla alan veya hesaplama gerektirmeyen bir tamsayıdır.

Yavaş efekt durduğunda, saatler hala kullanılıyor ve geçen sürenin% 100'ü kadar artırılıyor.

Bu da acele büyüler için işe yarayabilir.

@Sidar: İki seçenek görüyorum,

  1. Yaratık başına dahili saat. Yaratığın tekrar saldırmaya hazır olup olmadığını öğrenmek için: her saldırının son kullanılışını + yeniden şarj süresini kaydedin ve dahili saatin o saatten önce geçip geçmediğini kontrol edin.

  2. Saldırı başına bir zamanlayıcı: Saldırının yeniden şarj edilmesinin ne kadar sürdüğünü biliyorsunuz ve sadece bir zamanlayıcı ayarlıyor ve her turda * (1-yavaşlama%) geçen süreyi çıkarıyorsunuz.

Şahsen, işlem süresinden ve karmaşıklıktan tasarruf etmek için birden fazla zamanlayıcıyı ve kullanıcının bir dahili saati çıkarmayı tercih etmiyorum.

Gerçekten tercih edilir (Performansı o kadar etkilemez).


Dahili saatlere ihtiyaç yoktur. Nesnenize dt'nizin (delta time) ürününü artıran veya azaltan (bir şekilde) bağlayabileceğiniz bir çarpana iner Nesneleri gruplara veya ne anlama gelirse yönetebilirsiniz. Bence senin yolun biraz fazla olabilir. Ama hey işe yararsa ... o zaman işe yarar.
Sidar

@Sidar Bundan kaçınırsanız, muhtemelen sadece saldırı şarjı, Büyü süresi ve benzeri şeyler için saldırı başına bir saate ihtiyacınız olacaktır. En azından bu şekilde sadece bir saati güncellemeniz ve özelliklerin sıfırlanması için 'son aktivasyon' süresini tutmanız yeterlidir.
AturSams

Ancak sorusu oyuncu dışında çevreyi yavaşlatmakla ilgili. Bana göre, dt'yi 1'den düşük bir sayıyla çarpmanın en basit şekli gibi geliyor. Oyuncu için olduğu gibi tutarken.
Sidar

Ortamları yavaşlatmak, saldırı hızlarını ve diğer yeteneklerini (bir rpg olduğu için) yavaşlatmayı içerir, şarj süresine dayanan çeşitli mafya yetenekleri olabilir. İyileştirmeler, tutkular, debufflar, büyüler vb.
AturSams

2

Tesselode veya Bay Beast'in maruz kaldığı basit bir çözümle başlayabilirsiniz. Ancak, karmaşık şeyleri karıştırmaya başlarsanız, örneğin bir yavaşlama büyüsü yapılırken bir mermi zamanı , sıkışırsınız.

Bir saat hiyerarşisi uygulamanızı öneririm :

.
├── Main clock
│   └── UI clock
│   └── 3D clock
│       ├── GFX clock
│       └── Gameplay clock
│           └── Slowdown spell clock 01
│           └── Slowdown spell clock 02

Oyununuzdaki her şey saatin birinden delta zamanlarını kullanmalıdır: GFX saatinde grafik efektleri, Oyun saatinde AI ve animasyon çalışır, geçici bir Yavaşlama büyü saatinde çalışan yavaşlama büyüsünden etkilenen yaratıklar vb. hiyerarşinizin farklı bölümlerini etkiler: Yavaşlama büyüsü özel bir saat oluşturur ve etkiler; kurşun zamanı ise 3B saat hiyerarşisinin tamamını etkiler.


Teşekkürler, bu önemli bir içgörü. Ancak, bence basit tutacağımı düşünüyorum, çünkü özel durumumda aynı anda birden fazla yavaşlama etkisinin olacağı mantıklı değil.
David Miler

1

Biri oyunla ilgili bir zaman ve bir "gerçek" zaman için bir yerine iki farklı saate ihtiyacınız var.

currentGameTime = 0;
gameSpeed = 1.0f;
[...]
currentApplicationTime = GetTime():
timeDelta = (currentApplicationTime - lastApplicationTime)*gameSpeed;
currentGameTime += timeDelta;
lastApplicationTime = currentApplicationTime;

Daha sonra hızlandırmak (> 1) veya yavaşlamak (<1) için gameSpeed'i değiştirebilirsiniz. Oyuncunun farklı bir hızda hareket etmesi için zamanın yavaşlayıp yavaşlamadığını kontrol edin.

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.