Akıllı komut dizisini oyunumda nasıl uygulayabilirim?


18

Bir oyun motoru geliştiriyorum. Bir varlık / bileşen tabanlı bir varlık olması gerekiyordu. Oyunumu geliştirmek için, aslında varlıkları oluşturmak için bazı betik dillerini kullanmayı düşündüm.

Örneğin, oyuncuya agresif olan bir tür canavar eklemek istersem, çeşitli bileşenlere sahip bir varlık olacaktır; bu bileşenler canavar türüyle değişecek, bu yüzden oyunumda yüz farklı canavar türü varsa, oyunumda her biri için doğrudan oyun kodumda yeni bir yöntem oluşturmak zorunda kalmayacağım.

Bileşen olarak bu varlığı tanımlamak için bir komut dosyası dili kullanmalı mıyım yoksa daha iyi çalışacak başka bir şey var mı? Daha genel olarak, oyunumda komut dizisini nasıl kullanmalıyım?


Yalnızca varlık açıklaması için, komut dosyası oluşturmaya gerek olmadan yalnızca xml veya benzeri bir şey kullanabilirsiniz. Komut dosyası oluşturmak için C # kullanırım, ancak yalnızca motorunuz
.NET'deyse

@Kikaimaru C # Bir betik dili değildir. Lua kullanmak daha iyi bir fikir veya motorunuza yerleştirilebilecek başka bir dil olacaktır.
JDSweetBeat

@DJMethaneMan "C # komut dosyası dili değil" hiçbir şey ifade etmiyor, C # ile yazılmış bir oyunda C # dilinde komut dosyası yazma ve derleme için Roselyn gibi bir şey kullanma konusunda kesinlikle sorun yok ... Ama 4 yıl sonra json a xml ve C # yerine javascript :)
Kikaimaru

Yanıtlar:


17

Oyunum bir varlık bileşeni çerçevesi kullanıyor ve varlıkları tanımlamak için komut dosyaları kullanıyor (bu doğrudan davranışı tanımlamıyor, sonunda bunun hakkında daha fazla konuşacağım). Komut dosyaları, her bir varlığı oluşturmak için kullanılacak gerçek bileşenleri tanımlar. Oluşturduğum basit bir betik dili kullanıyor. İşte scriptlerimden birinin basitleştirilmiş bir versiyonu:

ENTITY:"Goblin"
{
    description="It's currently their age."
    commonname="goblin"
    pluralCommonName="goblins"
    childname="gob'in"
    pluralChildName="gob'ins"
    active=Nocturnal
    tags=Mobile
    baseAttributes="OrganicMobileCreature"

    [Model]{
            meshname="Goblin"
            texturename="GoblinTexture"
    }

    [Motion]{
            maxvelocity=0.01:0.015
            locomotion=Walk,Swim
    }

    [Skills]{
            ALL=0.01:0.05,Mine=8.3:8.8,PlaceCube=8.3:8.8
    }

    [Inventory]{
            maxItems=2
            Allow=ALL
            Disallow=NONE
    }
}

Bunların çoğu kendi kendini tanımlamaktadır, ancak işte bazı önemli noktalar:

  • İlk bölümde işletme için ortak bilgiler açıklanmaktadır. Bu, varlığın çeşitli yönleri için bir açıklama ve görünen adları içerir.
  • baseAttributesOrtak bileşenleri tanımlar başka komut dosyası istemiyorum bu etiket başvuruları birden çok kez yeniden tanımlamak zorunda. Gibi bileşenler içerir position, liferequirementsvb. Burada tekrar herhangi bir bileşen tanımlanmışsa, bu bileşen ortak bileşenin üzerine yazacaktır.
  • Her [NAME] { }set, bu varlıklara eklenecek yeni bir bileşen tanımlar.
  • Bu açıklama yalnızca tek bir varlık için değil , oluşturulan tüm goblinler için de geçerlidir. Bazı değerlerin aralıklara sahip olduğunu göreceksiniz (yani 0.01:0.015), yeni bir goblin oluşturulduğunda o aralıkta rastgele bir değere sahip bir bileşenle oluşturulur. Yani her cin biraz farklı becerilere ve biraz farklı hızlara sahip olacak. Bu kurulum, tüm goblinlerin küpleri ve madenciliği yerleştirmede gerçekten iyi becerilerle başlayacağını tanımlar, bu da sadece kendi test amacım içindir. Ama tahmin edebileceğiniz gibi, değerleri istediğim gibi değiştirmek çok kolay.

Tüm bunlar, özel bir ayrıştırıcı, varlık tanımlarını (benim Lexicon olarak adlandırıyorum!) Tutmak için bir tür yapı ve bu varlık tanımlarını almak ve yeni varlıklar oluşturmak için bir fabrika oluşturmayı içerir. Benim için bu sistem hala ilk aşamalarında, ama gerçekten, gerçekten iyi çıkıyor. Varlıkları hızlı bir şekilde tanımlamak için oldukça güçlü bir sistemdir ve oluşturduğunuz bileşenleri kullanarak istediğiniz varlıkları oluşturmanıza olanak tanır. Kendi ayrıştırıcıyı oluşturmakta rahat değilseniz, XML'in iyi çalışacağını düşünüyorum. Madeni, küçük bir programlama dili için yazdığım bir geri dönüş özyinelemeli ayrıştırıcıdan dönüştürdüm.

Gördüğünüz gibi bu, varlığı tanımlar. Doğrudan davranışı tanımlamadığından bahsettim. Bununla birlikte, nefret edilen düşmanlar ve söz konusu düşmanlara ne kadar agresif tepki vermeleri gibi şeyleri kolayca tanımlayabilir. Bu, bu tür bir davranışı kontrol etmek için kullandığınız bileşeni tanımlamak kadar basit olacaktır. Varlıklarımın ayrıca aşağıdakileri tanımlayan bir istihbarat bileşeni (gösterilmiyor) var:

  • Yol bulma yolları (basit görüş açısı hareketi, basit A ​​*, öngörülü A *, vb.)
  • Ne kadar agresif / savunmacı. Varlıklar savunulacak ev bölgelerine sahip olabilir, ancak bu bölgelerin dışında agresif olmayabilir.
  • Teknoloji bilinci (açık kapılar, alet kullanma, tuzaklardan kaçınma vb.)
  • Ve dahası...

Sizinki nasıl tanımlanırsa tanımlansın, bu bileşendeki verileri yönlendirecek olan sistem, bu da girişlerinizin davranışını etkiler.


Paylaşım için teşekkürler. Aslında XML biçimini kullanarak yapmaya çalışacağımı düşünüyorum. Ben bu konuda çok düşündüm (AbstractChaos btw sayesinde) ve benim ihtiyaçlarını ayak gerekir (en azından varlık açıklamaları için).
nathan

1
@nathan XML ile gitmeniz gerektiğine katılıyorum. Gönderimin nedeni, XML'inize hangi verilerin dahil edileceği ve nasıl kullanılacağıydı. Verilerin formatı istediğiniz gibi olabilir. Eklemeyi seçtiğiniz veriler ve kullanımını nasıl uyguladığınız çok daha önemlidir.
MichaelHouse

@ Byte56 Bu yazının eski olduğunu biliyorum, ancak ebeveyn-çocuk ilişkilerini nasıl ele alabilirsiniz? Bir Beceri ağacımız olduğunu ve A [1] 'i etkinleştirmek için A [0] yeteneğinde 10 puana ve A [2] vb. Etkinleştirmek için 10 puana ihtiyacınız olduğunu varsayalım. Bunları iç içe geçirmem veya düzleştirmem ve parentId? Açıkçası mantıklı bir şekilde eşdeğerler, ama umarım gerçek dünyaya dair bir kavrayışa sahip olursun.
Superstringcheese

@Superstringcheese if player.hasPoints(10) then i++ end skillTree[i]biraz sahte kod olurdu. Ancak bu sorunun yazı ile nasıl alakalı olduğu hakkında hiçbir fikrim yok.
JDSweetBeat

4

Gerçekten ihtiyacınız olan bir Canavar bileşenlerini tanımlamanın bir yoluysa, XML hem C # hem de java'nın yıldırım hızlı bir uygulaması vardır.

Xml'niz olabilir

<?xml version="1.0" encoding="UTF-8"?>
<mobs>
  <mob>
    <personality>Aggressive</personality>
    <intelligence>20</intelligence>
  </mob>
</mobs>

O zaman Mob sınıfın gibi görünebilir. (Java)

public class Mob {
  private IPersonality personality;
  private Integer intelligence

  //**  Getters & Setters **//
}

IPersonality bir arayüzdür.

Daha sonra xml'nizi yükleyebilir ve her değeri bir fabrika aracılığıyla ayrıştırabilirsiniz.

örneğin Kişilik Değerini PersonalityFactory'ye Ayrıştırın:

public IPersonality getPersonality(String personalityName) {
  if(personalityName.equals("Aggressive")) {
    return new AggressivePersonality();
  }
  else if(personalityName.equals("Passive")) {
    return new PassivePersonality();
  }
  else {
     //Maybe allow for no personality (We all know monster like that ;) )
     return null; 
  }
}

Sonra böyle bir mafya kurabilirsin

Mob mob = new Mob();
mob.setPersonality(getPersonality(xmlValue));
mobList.add(mob);

Anahtar, motorun xml formatını bilmesidir ve tüm ihtiyaçları için bir fabrikaya sahiptir.

Xml bir avantajı biçiminin doğru bkz daima olmasını sağlamak için kendi şema tanımlayabilirsiniz olmasıdır burada .

Bu yardımcı olur umarım


Aslında kolayca oyun geliştirme süreci üzerinde yeni varlık oluşturmak için bir yol bulmak gerekir. XML yeterince esnek olacak mı? Dahili oyun mantığı için yine de komut dosyası eklemem gerekecek.
nathan

Mob sınıfını Entity olarak okursanız, XML'yi farklı bileşenlerle (IPersonality, Intelligence [o mob için veri örneği]) kullanarak yeni bir Enitity (Mob) oluşturuyorsunuz. Ve ne yazık ki, belirttiğinizin dışında ne yapmasını istediğinizi bilmediğim için yeterince esnek olacaksa cevap veremem, ancak XML, her bölümü nasıl yorumladığınız tek sınırdır. Soruyu ayrıntılı bir örnekle güncelleyin ve bunu başarabilecek bir xml göstereceğim. Dahili oyun mantığı, dahili olması gerektiği gibi mi geliyor?
AbstractChaos

0

Python bence iyi. Programlarınıza komut dosyası oluşturma yetenekleri eklemek istiyorsanız genellikle LUA iyi bir alternatiftir.

Canavarlarınızın davranışını tanımlamak için XML kullanabilirsiniz, bu gerçek oyun kodunda bir miktar kodlama içerecektir, çünkü davranışa (hız, canavarın kullandığı silah türü, sadece "isim" veya bazı özellikleri kaydedeceksiniz) vb.) kullanmanız gerekir.

Bir Scriptengine (örn. LUA) kullanıyorsanız, bu kodu önceden derlenmiş programınızdan çalışma zamanı sırasında yüklenen script dosyalarına aktarabilirsiniz. Bunu yapmak için "canavarlar" ın API'sini scriptine maruz bırakmalısınız. Bu, dışarıdan canavar oyun kodu yöntemlerini çağırmanıza izin verir.


Canavarımın API'sı? Yani, senaryodan (örnekleme) yeni bileşenler oluşturabilmem gerekecek. Mümkün mü?
nathan

Afaik bu mümkün olmalı. Ayrıca harici depolama (abstractchaos veya byte56 tarafından belirtildiği gibi) ve komut dosyası dili (LUA, Python ...) gibi karışık bir yaklaşım da kullanabilirsiniz. Örneğin LUA'nın ana avantajı, kodunuzu çalışma zamanında değiştirebilmeniz ve koşan oyununuzda / motorunuzda anında kullanılabilir olmasıdır
Aron_dc

Ho ciddi mi? Gerçekten büyük bir avantaj. Ayrıca "oyun zaman çizelgesi" için LUA (veya diğer komut dosyası dili) olsa. Yani, oyuncunun engellenmesi gereken bazı senaryo sahneleri oluşturmak için, bu hareketli grafik buraya taşınmalı, buraya ışık tutmalı ... Yani belki de varlık yüklemesi için bir betik dili kullanabilir miyim? Ayrıca ben iyi olup olmadığını görmek için ne "yönetici" dediğim üzerinde varlık / bileşenleri yönetmek için geçerli yolu göstermek için başka bir soru göndereceğim.
nathan
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.