Oyun içi etkinlikleri yönetmenin en iyi yolu?


13

Bazı oyun içi etkinliklerin arada sırada yapılması gereken bir oyun üzerinde çalışıyorum. Güzel bir örnek bir öğretici olacaktır. Oyuna başlarsınız ve oyunun çeşitli noktalarında bir olay meydana gelir:

  • İlk düşmanınızla karşılaşırsınız, oyun duraklar ve onu nasıl öldüreceğinize dair bir açıklama alırsınız.
  • İlk düşmanı öldürdün, "iyi iş" mesajı alıyorsun.
  • Yeni bir öğe, öğe istatistikleri açılır penceresiyle bir menü kazanırsınız.
  • vs vs.

Üzerinde çalıştığım oyun, oyundaki kuralların hemen hemen aynı olduğu bir bulmaca oyunudur, bu yüzden tüm bu olayları ayrı seviyelerde sabit kodlamakta yetersiz görünüyor.

Bu olayları bir şekilde XML gibi harici bir kaynakta tanımlamalı mıyım? Sonra XML okuyan ve düzey için olay gereksinimlerini ayarlayan bir tercüman yazmak? Örneğin iki düşmanı öldürdüğünüzde meydana gelmesi gereken bir olayı nasıl tanımlayabileceğimden emin değilim.

Sadece açık olmak gerekirse, bunu yapmak için en iyi programlama dilini veya komut dosyası dilini aramıyorum, ancak daha fazlasını yapmak için en iyi yöntemde arıyorum.

Teşekkürler!


Düzenleme: Sorumun anlaşılması oldukça zor olduğu için ikinci bir örnek:

Yaşadığım sorun, oyuna hep aynı olan bir işlemle fazladan bazı eylemler koymak. Bir RPG savaşı gibi, herkesin bir dönüşü vardır, bir beceri alır vb. - her zaman aynıdır. Ama aralarında bir yerde bir cutscene göstermek istediğim bir durum olsaydı. Cutscene ile değiştirilmiş bir savaş sınıfına geçmek için tüm oyun yapısını değiştirmek çok verimsiz görünüyor. Bunun nasıl yapıldığını merak ediyorum.


8
Şeyleri aşırı genelleştirmeye çalışmayın, örneğin öğreticiler çok spesifiktir ve birçok farklı tetikleyici / etkinlikle birlikte gelir. Hardcoding / script ile yanlış bir şey yok.
Maik Semder

1
@Maik Eğer bir cevap kimliği +1 koyarsanız .. Basit ve çözülmüş her gün güzel daha iyidir.
James

İkinci örneğiniz, soyut bir mesajlaşma sisteminin büyük bir kazanç olacağını daha açık hale getiriyor. Bir öğretici için, şeyleri sadece başlangıçta sadece bir kez gerçekleştiği için zor kodlayabilirsiniz, ancak oyunun tüm süresi boyunca herhangi bir zamanda gerçekleşebilecek devam eden etkinlikler için, bu farklıdır.
jhocking

Hala biraz belirsiz, lütfen 3 farklı kesim için en az 3 tetikleyici listeleyin. genel olarak cevaplamak çok zor. Temel olarak, en iyi nasıl uygulanacağını anlamak için ortak bir desen bulmalısınız.
Maik Semder

Ne istiyorsun? Eylemleri duraklatmak ve ekstraları yapmak, sonra eylemleri duraklatmak mı istiyorsunuz?
user712092

Yanıtlar:


7

Bu, olayların oyununuzdaki nesneler arasında gerçekte nasıl iletildiğine çok bağlıdır. Örneğin, merkezi bir mesajlaşma sistemi kullanıyorsanız, belirli mesajları dinleyen ve belirli mesajları duyduğunda öğretici açılır pencereler oluşturan bir öğretici modülünüz olabilir. Ardından, bir XML dosyasında veya öğretici modül tarafından ayrıştırılan bir şeyde, hangi iletinin gösterileceğini ve hangi pop-up pencerenin gösterileceğini ayarlayabilirsiniz. Oyun durumunu izleyen ve oyunda bir şeyler fark ettiğinde öğretici açılır pencereleri görüntüleyen ayrı bir öğretici nesneye sahip olarak, öğretici nesneyi oyununuzla ilgili başka bir şey değiştirmeye gerek kalmadan istediğiniz zaman değiştirebilirsiniz. (Bu Observer modeli mi? Tüm tasarım modellerine aşina değilim.)

Genel olarak, bu konuda endişelenmeye değerse, eğitiminizin karmaşıklığına bağlıdır. Kodunuzdaki ve / veya seviyelerinizdeki olayları kodlamak sadece bir avuç öğretici pop-up için bana çok şey gibi gelmiyor. Her tetikleyiciyi yapmanız gereken tek şey öğretici modüle bir mesaj göndermektir, çünkü TutorialModule.show ("1st_kill");


Ben onun bir bulmaca oyunu beri onun mantığı birden çok seviye için tek bir konumda olduğunu ve böyle, biz bunun için süren bir şey olması için bir öğretici yapmak için kontroller yapmak. Dürüst olmak gerekirse bu bir bulmaca oyunuysa, bu en güzel kod olmasa bile bunun için büyük bir isabet alacağını sanmıyorum ve günün sonunda gemilerin her zaman -her zaman- Gün ışığını hiç görmeyen güzel koddan% 100 daha iyi;)
James

Gözlemci modeli gibi bir şeyi hiç düşünmemiştim, kulağa hoş bir çözüm gibi geliyor. Ben bir deneyeceğim, teşekkürler :)
omgnoseat

7

İşte onları anladığım gibi tasarım kısıtlamaları:

  1. Çekirdek oyun kodu seviye gereksinimlerini umursamıyor ve onlarla ilgilenen koda bağlanmamalıdır.

  2. Aynı zamanda, bu gereksinimleri karşılayan belirli olayların ne zaman gerçekleştiğini bilen temel oyun kodu (bir eşya almak, bir düşmanı öldürmek, vb.)

  3. Farklı seviyelerin farklı gereksinimleri vardır ve bunların bir yerde tanımlanması gerekir.

Bunlar göz önüne alındığında, muhtemelen şöyle bir şey yaparım: İlk olarak, bir oyun seviyesini temsil eden bir sınıf yapın. Bir seviyenin sahip olduğu özel gereksinimleri bir araya getirecektir. Oyun olayları meydana geldiğinde çağrılabilecek yöntemler vardır.

Çekirdek oyun koduna geçerli seviye nesnesine bir referans verin. Oyun olaylar gerçekleştiğinde, bunun üzerine yöntemlerini çağırarak seviyesini söyleyecektir: enemyKilled, itemPickedUpvb

Dahili olarak Levelbirkaç şeye ihtiyaç duyar:

  • Hangi olayların zaten gerçekleştiğini izlemek için durumu belirtin. Bu şekilde öldürülen ilk düşmanı diğerlerinden ayırabilir ve belirli bir eşyayı ilk kez aldığınızı bilir.
  • LevelRequirementBu seviye için ihtiyacınız olan belirli hedef kümesini tanımlayan nesnelerin listesi .

Bir seviyeye girdiğinizde Level, doğru LevelRequirements ile bir tane oluşturacak, oyun kodunu ayarlayacak ve bu seviyeyi vereceksiniz.

Bir oyun etkinliği her gerçekleştiğinde oynanış etkinliğe geçer Level. Bu da toplam verileri (öldürülen toplam düşman sayısı, öldürülen bu türden düşmanlar vb.) Hesaplar. Bir gereksinimin karşılanıp karşılanmadığını ve varsa ortaya çıkan davranışın uygun olup olmadığını görmek için bir test yapar (öğretici metin gösteriliyor, vb.)

LevelRequirement temelde iki şeye ihtiyaç duyar:

  1. Gereksinimin karşılanıp karşılanmadığını gösteren bir testin açıklaması . Bu, diliniz bunu kolaylaştırırsa bir işlev olabilir, aksi takdirde verileri modelleyebilirsiniz. (Yani bir var RequirementTypegibi şeylerle enum FIRST_KILLve sonra büyük bir switchbu konuda her türlü nasıl kontrol edileceğini bilir.)
  2. Gereksinim karşılandığında gerçekleştirilecek eylem.

Hala bu gereksinim kümelerinin nerede açıklandığı sorusu var. XML veya başka bir metin dosyası biçimi gibi bir şey yapabilirsiniz. Aşağıdaki durumlarda yararlıdır:

  1. Programcı olmayanlar yazma seviyeleri olacaktır.
  2. Yeniden derlemeden ve / veya yeniden başlatmadan gereksinimleri değiştirmek isteyebilirsiniz.

Bunlardan hiçbiri böyle değilse, muhtemelen sadece doğrudan kodda inşa ediyorum. Daha basit her zaman daha iyidir.


İlk 3 puan şu anda kullandığım yöntemin çok yakın bir açıklaması, etkileyici! Evet, en çok uğraştığım şey, gereksinimi nerede açıklayacağınız ve oyuna nasıl dönüştürüleceğidir (çünkü büyük olasılıkla harici bir şey olacak). Ayrıntılı açıklama için teşekkürler :)
omgnoseat

5

Bu olayları nasıl yapacağınızı bilmeniz gerektiğini düşündüm ve geri kalan kısım bununla ilgili, Sadece bu olayları saklamak istiyorsanız, sonra bazı ilişkisel veritabanı kullanın veya bunları metinle tanımlayın ve komut dosyası dilini kullanın (ayrıştırma ve değerlendirme yapacak) Sen). :)

İstediğiniz şey gerçekleşen olayları tanımaktır (1) ve daha sonra bu olayların talep ettiği bazı işlemleri yapmaktır (mesajı yazdır, tuşa basmayı kontrol et ...) (2). Ayrıca bu olayları yalnızca bir kez gerçekleştirmek istersiniz (3).

Temel olarak Koşulları kontrol etmek ve ardından bazı davranışlar planlamak istiyorsunuz.

Olayları tanıma (1)

  • Bu "karşılaşılan ilk düşman", "yeni eşya kazanıldı" gibi olayları tanımak istiyorsunuz
  • eğer jenerik parça olursa, " düşmanla karşılaşıldı ", " eşya kazandı " Belirli bir parçayı " önce ..." kontrol edersiniz , " yeni eşya kazanılır"

Olaylar nelerden oluşur?

Daha genel bir bakış açısıyla, bu tür her bir olay aşağıdakilerden oluşur:

  • önkoşullar , sen onları kontrol et
  • önkoşullar karşılandığında yapılacak eylemler ("İlk düşmanı öldürdün!" deyin, "" A ve B düğmelerine basarak kombinasyon yapın "," devam etmek için "enter" tuşuna basın, "enter" tuşuna basın)

Bu etkinlikler nasıl saklanır?

Bazı veri yapılarında:

  • önkoşullar listesi bulundurun (üst düzey bir dilde yazıyorsanız dizeler veya kodlar)
  • eylem listesi var (bunlar dize olabilir, Quake motoru etkinlikler için dizeleri kullanır)

Ayrıca ilişkisel veritabanında saklayabilirsiniz, gerekli görünmüyorsa, bu oyunu büyük yapmak istiyorsanız bir tane yapmanız gerekebilir.

Daha sonra bu dizeleri / şeyleri ayrıştırmalısınız. Veya Python veya LUA gibi bir betik dili veya LISP gibi bir dil kullanabilirsiniz, hepsi sizin için onu ayrıştırabilir ve yürütebilir. :)

Bu olaylar oyun döngüsünde nasıl kullanılır (2)

Bu iki veri yapısına ihtiyacınız olacak:

  • etkinlik sırası (çalıştırılması planlanan etkinlikler buraya konur)
  • eylem sırası (zamanlanmış eylemler, olaylar hangi eylemlerin yapıldığını gösterir)

Algoritma:

  • Sen bazı tanımak ise olay 'in ön şartlar yerine getirilirse Sen içine koydular olay kuyruğuna
  • (3) Sonra bu etkinliğin yalnızca bir kez olmasını istediğinizden emin olmalısınız :) (örneğin, boolean dizisi has_this_event_happened ["ilk düşmanla karşılaştı"])
  • (eğer eylem sırası sonra, boş) orada olay ise kuyruk olayı Onun koydu eylemleri içine eylem kuyruğundan ve onu kaldırmak olay kuyruğuna
  • Orada ise eylem içinde eylem sıraya Bunu tarafından talep ne yapmaya başlamak
  • Böyle bir işlem yapılırsa, eylem kuyruğundan kaldırırsınız

Bu eylemlerin kendisi nasıl yapılır (2)

"Güncelle" işlevine sahip nesnelerin listesini yaparsınız. Bazen varlıklara (Quake motorunda) veya aktörlere (Unreal motorunda) denir.

  1. Bu nesneleri eylem sırasında başlatılmaları istendiğinde başlatırsınız.
  2. bu nesne diğer zamanlayıcılar gibi başka şeyler için de kullanılabilir. Quake'te bu varlıklar tüm oyun mantığı için kullanılır, bu konuda bazı materyalleri okumanızı tavsiye ederim .

Eylem "bir şey söyle"

  1. Ekranda bir şey yazdırıyorsunuz
  2. Bu mesajın birkaç saniye görünmesini istiyorsunuz
  3. "güncelleme" bölümünde:
    • remove_me_after değişkenini yapın ve geçen zamana kadar azaltın
    • değişken 0 olduğunda Bu eylemi eylem kuyruğundan kaldırırsınız
    • Bu nesneyi de kaldırırsınız (veya kaldırılmak üzere zamanlanırsınız ...)

İşlem "anahtar gerektir"

  1. Nasıl yapmak istediğinize bağlı, ama bence sen bir mesaj yazıyorsun
  2. "güncelleme" "bölümünde:
    • Sadece istenen tuşa basma olayını kontrol edin
    • Tuşa basma olaylarını tutmak için muhtemelen bir dizi / sıraya ihtiyacınız var
    • sonra eylem kuyruğundan kaldırabilir ve nesneyi kaldırabilirsiniz

Öğrenilecek yöntemler


-1 sağ, ya da sadece bir işlevi çağırıyor, cidden, OP sadece belirli bir koşul karşılandığında bir mesaj kutusu istiyor
Maik Semder

Bu çok güzel bir yazma, ama tam olarak ne aradığını değil. Ne istediğimi açıklamakta zorlandım. İkinci bir açıklama ekledim: Yaşadığım sorun, oyuna her zaman hemen hemen aynı olan bir işlemle bazı ek eylemler koymak. Bir RPG savaşı gibi, herkesin bir dönüşü vardır, bir beceri alır vb. - her zaman aynıdır. Ama ya arada bir yerde bir sahneyi göstereceğim bir olay olsaydı. Değiştirilen bir savaş sınıfında yer alan cutsene ile tüm oyun yapısını değiştirmek çok verimsiz görünüyor. Bunun nasıl yapıldığını merak ediyorum.
omgnoseat
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.