Audio3D

Stránka aktualizovaná :
Dátum vytvorenia strany :

Poznámky k týmto tipom

Táto vzorka je založená na programoch publikovaných na nasledujúcich lokalitách. Trochu mením kód, aby som ho ľahšie pochopil a vysvetlil v japončine. V podstate používame pôvodný kód tak, ako je, takže ak ho skutočne prijmete vo svojom hernom programe, opravte ho včas a použite ho.

Referenčná lokalita

Okrem toho je to vysvetlené za predpokladu, že máte niektoré základné znalosti o MonoGame a XNA. Pozrite si tipy monogame a tipy XNA pre hrubo.

Najmä preto, že matematika, vektory, trigonometrické funkcie, matrice atď. sú nevyhnutné, takže prosím vedieť, čo sú do určitej miery.

životné prostredie

nástupište
  • Windows 10
  • Kód je možné použiť na iných platformách s podporou monogame
Vizuálne štúdio
  • Visual Studio 2019
.NET Core
  • 3.1
Monogame
  • 3.8

Informácie o vzorkách

Na základe polohy kamery môžete počuť volanie z pozície psa a polohy mačky. Mačka krúži a krúži okolo pôvodu a hráč môže ovládať polohu fotoaparátu pomocou kľúča. Uistite sa, že spôsob, akým počujete zvuk, sa mení s každou zmenou polohy fotoaparátu alebo polohy mačky. Myslím, že je ľahké pochopiť pomocou slúchadiel. Nie som potvrdený na kanáli 5.1.

Ako pracovať

Čo robiť Klávesnica Gamepad (XInput) Mouse Touch
Fotoaparát dopredu a dozadu ↑↓ Ľavá palica (hore a dole) - -
Zmena orientácie fotoaparátu ←→ Ľavá palica (ľavá a pravá) - -
Koniec hry Esc Chrbát - -

Čo pripraviť

  • Psí pískací zvukový súbor
  • Tri mačacie pískacie zvukové súbory
  • Súbor obrázka psa
  • Súbor obrázka mačky
  • Súbor s obrázkom na zemi

Pôvodná vzorka na oficiálnych stránkach používa predpripravené súbory .xnb . Ak chcete ponechať vzorky na oficiálnych stránkach, nepoužívajte mgcbs, pridajte ich priamo do riešenia Visual Studio a skopírujte ich v čase zostavenia.

Neviem, prečo pôvodná vzorka používa túto metódu, ale myslím si, že je to pravdepodobne preto, že migrujeme staršie verzie projektu tak, ako je. Samozrejme, môžete použiť mgcb na generovanie rovnakého súboru. Projekty, ktoré je možné stiahnuť na tejto stránke, boli upravené na verziu MGCB.

program

Stiahnite si program pre všetky kódy.

Táto vzorka je navrhnutá tak, aby kód vyzeral trochu všeobecnejšie a zároveň aby prehrávanie zvuku vyzeralo dobre počas behu. Použitie iba Audio3D by bolo oveľa menej kódu, ale je popísané pozdĺž pôvodnej vzorky. Nechám si tie menej dôležité časti.

Projekt pozostáva z nasledujúcich súborov kódu:

  • Audio3DGame
  • AudioManager
  • Mačka
  • Pes
  • IAudioEmitter
  • Program
  • QuadDrawer
  • SpriteEntita

Trieda QuadDrawer

Táto trieda je triedou pomocníka pre kreslenie obdĺžnikových polygónov. Obdĺžnikové polygóny sa často používajú predovšetkým na zobrazenie 3D sprites (billboardov). Tieto tipy sa používajú pre billboardy pre mačky a psy, ako aj pre obdĺžnikové displeje zeme.

Táto trieda nemá nič spoločné s Audio3D.

pole

readonly GraphicsDevice _graphicsDevice;
readonly AlphaTestEffect _effect;
readonly VertexPositionTexture[] _vertices;

Minimálne informácie potrebné na nakreslenie polygónov. Nakreslite polygóny z údajov vrcholu bez prípravy údajov modelu.

staviteľ

/// <summary>
/// 新しい四辺形の描画ワーカーを作成します。
/// </summary>
public QuadDrawer(GraphicsDevice device)
{
  _graphicsDevice = device;

  _effect = new AlphaTestEffect(device);

  _effect.AlphaFunction = CompareFunction.Greater;
  _effect.ReferenceAlpha = 128;

  // 4つの頂点の配列を事前に割り当てます。
  _vertices = new VertexPositionTexture[4];

  _vertices[0].Position = new Vector3(1, 1, 0);
  _vertices[1].Position = new Vector3(-1, 1, 0);
  _vertices[2].Position = new Vector3(1, -1, 0);
  _vertices[3].Position = new Vector3(-1, -1, 0);
}

Keďže táto trieda je všeobecne použiteľná, dostanete GraphicsDevice inštanciu vytvorenú v procese inicializácie triedy hier.

Tu nastavíme efekt potrebný na nakreslenie spritu a polohu 4 vrcholov potrebných pre obdĺžnikový polygón. Veľkosť by sa mala pri kreslení zmenšiť, takže je -1 až 1.

Metóda DrawQuad

/// <summary>
/// 3Dワールドの一部として四角形を描画します。
/// </summary>
public void DrawQuad(Texture2D texture, float textureRepeats, Matrix world, Matrix view, Matrix projection)
{
  // 指定されたテクスチャとカメラマトリックスを使用するようにエフェクトを設定します。
  _effect.Texture = texture;

  _effect.World = world;
  _effect.View = view;
  _effect.Projection = projection;

  // 指定された数のテクスチャの繰り返しを使用するように頂点配列を更新します。
  _vertices[0].TextureCoordinate = new Vector2(0, 0);
  _vertices[1].TextureCoordinate = new Vector2(textureRepeats, 0);
  _vertices[2].TextureCoordinate = new Vector2(0, textureRepeats);
  _vertices[3].TextureCoordinate = new Vector2(textureRepeats, textureRepeats);

  // 矩形を描画します。
  _effect.CurrentTechnique.Passes[0].Apply();

  _graphicsDevice.DrawUserPrimitives(PrimitiveType.TriangleStrip, _vertices, 0, 2);
}

Nastaví prejdenú textúru na obdĺžnik a nakreslí ju. Keďže ide o základný proces, nie je čo si všimnúť.

Ak existuje jeden bod, v textureRepeats argumente je možné zadať premennú, aby bolo možné zmeniť súradnice textúry. Ak vertexPositionTexture.TextureCoordinate je nastavený nad rozsah 0 až 1, textúra je predvolene opakovane nakreslená. Pomocou neho je možné vyjadriť, že dlaždice môžu byť usporiadané opakovane. V skutočnosti sa zdá, že kockované vzory na zemi majú niekoľko jednoduchých čiernobielych obrázkov zoradených.

Rozhranie IAudioEmitter

/// <summary>
/// 3D サウンドを再生するエンティティの位置と速度を検索するために AudioManager が使用するインターフェイス。
/// </summary>
public interface IAudioEmitter
{
  Vector3 Position { get; }
  Vector3 Forward { get; }
  Vector3 Up { get; }
  Vector3 Velocity { get; }
}

Definovaná ako entita, ktorá vyžaruje zvuk. Keďže entity, ktoré tentokrát emitujú zvuk, sú psy a mačky, sú zdedené vo svojich príslušných triedach. Emitor potrebuje nasledujúce informácie:

Používanie vlastností
Pozícia Pozícia entity
Dopredu Smer, ktorým smeruje entita (vektor)
Hore Vzostup subjektu. Smer, v ktorom hlava existuje v osobe
Rýchlosť Rýchlosť, akou sa entita pohybuje. Používa sa na výpočet Dopplerových hodnôt.

Trieda SpriteEntity

Trieda na reprezentáciu 3D sprites (billboardy). Je tiež emitorom a dedí IAudioEmitter . Psy a mačky zdedia túto triedu.

majetok

/// <summary>エンティティの3D位置を取得または設定します。</summary>
public Vector3 Position { get; set; }

/// <summary>エンティティが向いている方向を取得または設定します。</summary>
public Vector3 Forward { get; set; }

/// <summary>このエンティティの上方向を取得または設定します。</summary>
public Vector3 Up { get; set; }

/// <summary>このエンティティの移動速度を取得または設定します。</summary>
public Vector3 Velocity { get; protected set; }

/// <summary>このエンティティの表示に使用されるテクスチャを取得または設定します。</summary>
public Texture2D Texture { get; set; }

Má informácie o polohe subjektu atď. V podstate mám informácie ako emitor. Je to tiež kresliaca entita, takže má tiež obrázok (Textúra), ktorý sa má zobraziť.

Metóda aktualizácie

/// <summary>
/// エンティティの位置を更新し、サウンドを再生できるようにします。
/// </summary>
public abstract void Update(GameTime gameTime, AudioManager audioManager);

Popisuje pozíciu entity a proces prehrávania zvuku, ale implementuje ju do odvodenej triedy.

Metóda kreslenia

/// <summary>
/// エンティティをビルボードスプライトとして描画します。
/// </summary>
public void Draw(QuadDrawer quadDrawer, Vector3 cameraPosition, Matrix view, Matrix projection)
{
  Matrix world = Matrix.CreateTranslation(0, 1, 0) *
                 Matrix.CreateScale(800) *
                 Matrix.CreateConstrainedBillboard(Position, cameraPosition, Up, null, null);

  quadDrawer.DrawQuad(Texture, 1, world, view, projection);
}

Psy a mačky majú rôzne obrázky a polohy, ale druhý mechanizmus kreslenia je úplne rovnaký, takže ich tu opisujem.

Každá transformácia a textúra prechádza do QuadDrawer, aby sa zobrazil obdĺžnikový polygón. Keďže koordinácia transformácie je základnou znalosťou, vysvetlenia nie sú zahrnuté.

Matrix.CreateConstrainedBillboard Použite metódy a informácie o kamere na jednoduché znázornenie billboardov, takže ich efektívne využite.

Trieda psov

Je to trieda, ktorá robí kreslenie psov a prehrávanie spevu. SpriteEntity Zdediť triedu. Pes zostáva v pevnej polohe v 3D priestore.

pole

/// <summary>サウンドを開始または停止するまでの時間。</summary>
TimeSpan _timeDelay = TimeSpan.Zero;

/// <summary>現在再生中のサウンド(ある場合)。</summary>
SoundEffectInstance _activeSound = null;

_timeDelay používa sa v intervaloch na hranie plaču.

SoundEffectInstance _activeSound Je to príklad pre hranie zvuku. SoundEffectInstance Ako často vidíte v triede prehrávania zvuku, môžete ho použiť tak, ako je to v 3D zvuku. Mimochodom _activeSound , neskôr dostanem odkaz z triedy AudioManager, takže ho nevyhodím na strane triedy Bodka.

Metóda aktualizácie

/// <summary>
/// 犬の位置を更新し、音を鳴らします。
/// </summary>
public override void Update(GameTime gameTime, AudioManager audioManager)
{
  // エンティティを固定位置に設定します。
  Position = new Vector3(0, 0, -4000);
  Forward = Vector3.Forward;
  Up = Vector3.Up;
  Velocity = Vector3.Zero;

  // 時間遅延がなくなった場合は、ループ音を開始または停止します。 これは通常は永久に続きますが、6秒の遅延後に停止し、さらに4秒後に再起動します。
  _timeDelay -= gameTime.ElapsedGameTime;

  if (_timeDelay < TimeSpan.Zero)
  {
    if (_activeSound == null)
    {
      // 現在再生中のサウンドがない場合は、トリガーします。
      _activeSound = audioManager.Play3DSound("DogSound", true, this);

      _timeDelay += TimeSpan.FromSeconds(6);
    }
    else
    {
      // それ以外の場合は、現在のサウンドを停止します。
      _activeSound.Stop(false);
      _activeSound = null;

      _timeDelay += TimeSpan.FromSeconds(4);
    }
  }
}

V tejto vzorke zostáva pes dlho v rovnakej polohe, takže prvé štyri parametre sú špecifikované rozhodujúcim úderom. Kreslenie sa vykonáva v základnej triede.

_timeDelay sa potom používa ako zostávajúci čas na zastavenie, hranie plaču.

AudioManager bude reprodukovanýPlay3DSound v 3D priestore odovzdaním názvu výkriku, informácií o slučke a vlastných informácií ako vysielača.

Trieda psov je navrhnutá tak, aby slučkovala plač, takže nemusíte premýšľať príliš hlboko, pretože je to len úprava, ako je hranie alebo zastavenie vetvenia.

Trieda mačiek

Je to trieda, ktorá robí mačacie kreslenie a spievanie prehrávania. SpriteEntity Zdediť triedu. Mačka sa pohybuje okolo pôvodu.

pole

/// <summary>次の音を鳴らすまでの時間。</summary>
TimeSpan _timeDelay = TimeSpan.Zero;

/// <summary>サウンドバリエーションから選択するための乱数ジェネレータ。</summary>
static readonly Random _random = new Random();

_timeDelay používa sa rovnakým spôsobom ako trieda psov, zvyšok času pred ďalším pískaním.

Existujú tri typy mačacích hovorov, ktoré sú náhodne vybrané a prehrávané, ale nemajú nič spoločné s Audio3D, pretože sú bonusovým prvkom.

Metóda aktualizácie

/// <summary>
/// 猫の位置を更新し、音を鳴らします。
/// </summary>
public override void Update(GameTime gameTime, AudioManager audioManager)
{
  // 猫を大きな円で動かします。
  double time = gameTime.TotalGameTime.TotalSeconds;

  float dx = (float)-Math.Cos(time);
  float dz = (float)-Math.Sin(time);

  Vector3 newPosition = new Vector3(dx, 0, dz) * 6000;

  // エンティティの位置と速度を更新します。
  Velocity = newPosition - Position;
  Position = newPosition;
  if (Velocity == Vector3.Zero)
  {
    Forward = Vector3.Forward;
  }
  else
  {
    Forward = Vector3.Normalize(Velocity);
  }

  Up = Vector3.Up;

  // 時間遅延がなくなった場合は、別の単発音をトリガーします。
  _timeDelay -= gameTime.ElapsedGameTime;

  if (_timeDelay < TimeSpan.Zero)
  {
    // 異なる3つのサウンドバリエーション(CatSound0、CatSound1、CatSound2)からランダムに選択します。
    string soundName = "CatSound" + _random.Next(3);

    audioManager.Play3DSound(soundName, false, this);

    _timeDelay += TimeSpan.FromSeconds(1.25f);
  }
}

Keďže mačka otáča pôvod kruhovým pohybom, spracováva ju tak, aby pohybovala trajektóriou kruhu pomocou trigonometrickej funkcie. V dôsledku toho sa poloha, dopredu a rýchlosť zmenili jeden po druhom. Preto, keď spustíte program, môžete vidieť, že plač mačky krúži okolo, aj keď fotoaparát nepohybujete.

_timeDelay Nasledujúci kód je proces, v ktorom je plač mačky náhodne priradený a hrá sa v pravidelných intervaloch. audioManager.Play3DSound Prechádzam sa na metódu, ktorá je emitorom. Môžete vidieť, že poloha prehrávania zvuku sa mení jeden po druhom.

Trieda AudioManager

To je konečne podstata Audio3D. 3D zvuk sa skladá z poslucháča a vysielača. Emitor už definuje psov a mačky, takže trieda AudioManager definuje poslucháčov. Zvyčajne existuje viac emitorov, zatiaľ čo existuje len jeden poslucháč.

Táto trieda dedí aGame registruje GameComponent a používa súčasť v triede.

Trieda ActiveSound

/// <summary>
/// アクティブな3Dサウンドを追跡し、アタッチされているエミッターオブジェクトを記憶するための内部ヘルパークラス。
/// </summary>
private class ActiveSound
{
  public SoundEffectInstance Instance;
  public IAudioEmitter Emitter;
}

Je definovaný v spodnej časti kódu, ale je to trieda na zachovanie štátu, ktorý hrá. Obsahuje informácie o prehrávanej zvukovej inštancii a prehrávaní emitora.

pole

// このマネージャーにロードされるすべてのサウンドエフェクトのリスト。
static string[] _soundNames =
  {
    "CatSound0",
    "CatSound1",
    "CatSound2",
    "DogSound",
  };

/// <summary>音を聞くリスナーの情報です。これは通常カメラに一致するように設定されます。</summary>
public AudioListener Listener { get; } = new AudioListener();

/// <summary>AudioEmitter は、3Dサウンドを生成しているエンティティを表します。</summary>
readonly AudioEmitter _emitter = new AudioEmitter();

/// <summary>再生可能なすべての効果音を保存します。</summary>
readonly Dictionary<string, SoundEffect> _soundEffects = new Dictionary<string, SoundEffect>();

/// <summary>現在再生中のすべての3Dサウンドを追跡します。また、再生が終わったインスタンスの破棄にも使用します。</summary>
readonly List<ActiveSound> _activeSounds = new List<ActiveSound>();

_soundNames definuje názov zvukového súboru (názov majetku), ktorý sa má načítať. Keďže ide o vzorový program, je definovaný tak, aby sa zvukový súbor najprv hromadne načítal. Importované zvukové údaje sú _soundEffects uložené v systéme .

AudioListener Listener Je to definícia poslucháča. Informácie o poslucháčovi sú definované, pretože public sú nastavené z triedy Hry.

AudioEmitter _emitter je definícia emitora pri aplikácii 3D na prehrávanie zvuku. V tejto vzorke je pri prehrávaní zvuku nastavená _emitter hodnota každého objektu emitora , takže je to formulár, ktorý ho zdieľa ako inštanciu. Samozrejme, môžete mať pre každý AudioEmitter objekt.

_activeSounds obsahuje informácie o zvuku, ktorý hráte v triede, ktorú ste definovali ActiveSound skôr. Keďže informácie o emitéri sa neustále menia, používajú sa na aktualizáciu informácií o polohe atď. a na zahodenie zvukových inštancií, ktoré sa skončili pri prehrávaní.

staviteľ

public AudioManager(Game game) : base(game) { }

GameComponent Keďže triedu zdedí, Game dostane inštanciu a odovzdá ju základnej triede.

Inicializácia metódy

/// <summary>
/// オーディオマネージャを初期化します。
/// </summary>
public override void Initialize()
{
  // ゲームの世界のスケールと一致するように、3Dオーディオのスケールを設定します。
  // DistanceScale は、離れるにつれて音量が変化する音の量を制御します。
  // DopplerScale は、サウンドを通過するときにピッチが変化するサウンドの量を制御します。
  SoundEffect.DistanceScale = 2000;
  SoundEffect.DopplerScale = 0.1f;

  // すべての効果音をロードします。
  foreach (string soundName in _soundNames)
  {
    _soundEffects.Add(soundName, Game.Content.Load<SoundEffect>(soundName));
  }

  base.Initialize();
}

GameComponent Pretože zdedí triedu, automaticky sa zavolá pri inicializácii.

SoundEffect.DistanceScale a SoundEffect.DopplerScale sú to parametre venované static 3D zvuku.

SoundEffect.DistanceScale Počuť zvuk aj v diaľke.

SoundEffect.DopplerScale Je to vplyv Dopplerovho efektu. Čím vyššie číslo, tým väčší je Dopplerov efekt.

_soundNames Uloženie názvu majetku definovaného v slučke na načítanie _soundEffects .

Metóda likvidácie

/// <summary>
/// 効果音データをアンロードします。
/// GameComponent として登録すればゲーム終了時に自動的に呼ばれます。
/// </summary>
protected override void Dispose(bool disposing)
{
  try
  {
    if (disposing)
    {
      foreach (SoundEffect soundEffect in _soundEffects.Values)
      {
        soundEffect.Dispose();
      }

      _soundEffects.Clear();
    }
  }
  finally
  {
    base.Dispose(disposing);
  }
}

GameComponent Automaticky sa nazýva na konci hry, pretože zdedí triedu.

Zničenie všetkých dovezených zvukových aktív.

Metóda aktualizácie

/// <summary>
/// 3Dオーディオシステムの状態を更新します。
/// </summary>
public override void Update(GameTime gameTime)
{
  // 現在再生中のすべての3Dサウンドをループします。
  int index = 0;

  while (index < _activeSounds.Count)
  {
    ActiveSound activeSound = _activeSounds[index];

    if (activeSound.Instance.State == SoundState.Stopped)
    {
      // 音の再生が終了した場合は廃棄してください。
      activeSound.Instance.Dispose();

      // アクティブリストから削除します。
      _activeSounds.RemoveAt(index);
    }
    else
    {
      // サウンドがまだ再生されている場合は、3D設定を更新します。
      Apply3D(activeSound);

      index++;
    }
  }

  base.Update(gameTime);
}

GameComponent Pretože zdedí triedu, automaticky sa zavolá v procese aktualizácie.

Skontrolujte aktuálne prehrávaný zvuk a ak sa Apply3D prehráva, zavolajte metódu na aktualizáciu polohy zvuku tak, aby zodpovedala vysielaču. Ak niektorý zvuk skončil prehrávanie, inštancia sa zahodí.

Metóda Play3DSound

/// <summary>
/// 新しい3Dサウンドを設定し再生します。
/// </summary>
public SoundEffectInstance Play3DSound(string soundName, bool isLooped, IAudioEmitter emitter)
{
  ActiveSound activeSound = new ActiveSound();

  // インスタンスを生成し、インスタンス、エミッターを設定します。
  activeSound.Instance = _soundEffects[soundName].CreateInstance();
  activeSound.Instance.IsLooped = isLooped;

  activeSound.Emitter = emitter;

  // 3D 位置を設定します。
  Apply3D(activeSound);

  activeSound.Instance.Play();

  // このサウンドがアクティブであることを保存します。
  _activeSounds.Add(activeSound);

  return activeSound.Instance;
}

Proces prehrávania 3D zvuku zvonku. Má názov zvuku na prehrávanie, či už na slučku a informácie o vyžarovaní.

Ak chcete prehrať zvuk, vytvorte novú inštanciu zvuku zo zvukového zdroja, ktorý uchovávate v _soundEffects. SoundEffectInstance môže mať aj slučku alebo nie, takže nastavte informácie o slučke.

Keďže vytváram ako ActiveSound stav prehrávania, nastavím informácie o emitore, ktoré sú objektom prehrávania zvuku. Ak chcete použiť 3D informácie o polohe na zvuk, získate Emitter hodnotu, ktorú potrebujete.

Apply3D Metóda je popísaná nižšie, ale je to proces aplikácie 3D informácií z emitora na zvuk.

Základným procesom 3D zvuku je spustenie prehrávania pomocou SoundEffectInstance.Play 3D množiny informácií. Zvyšok je pravidelne aktualizovať 3D informácie, až kým sa zvuk nedokončí.

Metóda Apply3D

/// <summary>
/// 3Dサウンドの位置と速度の設定を更新します。
/// </summary>
private void Apply3D(ActiveSound activeSound)
{
  _emitter.Position = activeSound.Emitter.Position;
  _emitter.Forward = activeSound.Emitter.Forward;
  _emitter.Up = activeSound.Emitter.Up;
  _emitter.Velocity = activeSound.Emitter.Velocity;

  activeSound.Instance.Apply3D(Listener, _emitter);
}

Proces aplikácie 3D efektu na zadanú zvukovú inštanciu pomocou poslucháčov a vysielačov.

Zakaždým nastavíme hodnotu na _emitter bežnej inštancie. Ak ho už AudioEmitter máte SoundEffectInstance.Apply3D , jednoducho odovzdajte poslucháčovi a emitorovi metódu.

Trieda Audio3DGame

Poďme sa teda pozrieť na to, o čom je hracia trieda.

pole

readonly GraphicsDeviceManager _graphics;
readonly AudioManager _audioManager;
readonly SpriteEntity _cat;
readonly SpriteEntity _dog;

/// <summary>地面の描画に使用するテクスチャーです。</summary>
Texture2D _checkerTexture;

QuadDrawer _quadDrawer;

Vector3 _cameraPosition = new Vector3(0, 512, 0);
Vector3 _cameraForward = Vector3.Forward;
Vector3 _cameraUp = Vector3.Up;
Vector3 _cameraVelocity = Vector3.Zero;

KeyboardState _currentKeyboardState;
GamePadState _currentGamePadState;

AudioManager Zaregistruje sa GameComponents , ale má ho ako pole, pretože k nemu pristupuje individuálne.

Iní definujú entity psov, mačiek, textúry pre kreslenie zeme, kvaddrawer, informácie o kamere a vstupné informácie.

staviteľ

public Audio3DGame()
{
  Content.RootDirectory = "Content";

  _graphics = new GraphicsDeviceManager(this);

  _audioManager = new AudioManager(this);

  // AudioManager を Components に追加して自動的に Update メソッドが呼ばれるようにします。
  Components.Add(_audioManager);

  _cat = new Cat();
  _dog = new Dog();
}

AudioManager Generujte a GameComponents zaregistrujte sa na .

Vytvorili ste aj triedy mačiek a psov.

Metóda LoadContent

/// <summary>
/// グラフィックコンテンツをロードします。
/// </summary>
protected override void LoadContent()
{
  _cat.Texture = Content.Load<Texture2D>("CatTexture");
  _dog.Texture = Content.Load<Texture2D>("DogTexture");

  _checkerTexture = Content.Load<Texture2D>("checker");

  // 四角形ポリゴンを描画するためのクラス
  _quadDrawer = new QuadDrawer(_graphics.GraphicsDevice);
}

Vložte textúry potrebné pre každú kresbu.

QuadDrawer je GraphicsDevice tu generovaný, pretože vyžaduje .

Metóda aktualizácie

/// <summary>
/// ゲームがロジックを実行できるようにします。
/// </summary>
protected override void Update(GameTime gameTime)
{
  HandleInput();

  UpdateCamera();

  // 新しいカメラの位置について AudioManager に伝えます。
  _audioManager.Listener.Position = _cameraPosition;
  _audioManager.Listener.Forward = _cameraForward;
  _audioManager.Listener.Up = _cameraUp;
  _audioManager.Listener.Velocity = _cameraVelocity;

  // ゲームエンティティに動き回って音を鳴らすように伝えます。
  _cat.Update(gameTime, _audioManager);
  _dog.Update(gameTime, _audioManager);

  base.Update(gameTime);
}

HandleInput Metódy a UpdateCamera metódy sú proces získavania vstupu zariadenia a manipulácie s kamerou, o ktorom sa bude diskutovať neskôr.

Keďže poloha fotoaparátu a pozícia poslucháča sú takmer vždy rovnaké, poslucháč je po procese aktualizácie fotoaparátu nastavený na rovnakú hodnotu.

_cat Zavolajte na metódy a _dog aktualizovať pohyb a pískanie.

Metóda kreslenia

/// <summary>
/// ゲームが描画する必要があるときに呼び出されます。
/// </summary>
protected override void Draw(GameTime gameTime)
{
  var device = _graphics.GraphicsDevice;

  device.Clear(Color.CornflowerBlue);

  device.BlendState = BlendState.AlphaBlend;

  // カメラ行列を計算します。
  var view = Matrix.CreateLookAt(_cameraPosition, _cameraPosition + _cameraForward, _cameraUp);
  var projection = Matrix.CreatePerspectiveFieldOfView(1, device.Viewport.AspectRatio, 1, 100000);

  // チェッカーグラウンドポリゴンを描画します。
  var groundTransform = Matrix.CreateScale(20000) * Matrix.CreateRotationX(MathHelper.PiOver2);

  _quadDrawer.DrawQuad(_checkerTexture, 32, groundTransform, view, projection);

  // ゲームエンティティを描画します。
  _cat.Draw(_quadDrawer, _cameraPosition, view, projection);
  _dog.Draw(_quadDrawer, _cameraPosition, view, projection);

  base.Draw(gameTime);
}

Generuje transformácie zobrazenia a projekcie z informácií o kamere.

Pre zem sa obdĺžnik nakreslený v QuadDrawer zobrazuje vertikálne, takže sa otáča tak, aby bol horizontálny a mierne zväčšený. _quadDrawer.DrawQuad Druhý argument metódy určuje počet opakovaní textúry, ktorý určuje, že hárky 32x32 sa zobrazia vedľa seba.

_cat a _dog sú interne billboardované, takže informácie o polohe kamery sa odovzdávajú a kreslia.

Metóda HandleInput

/// <summary>
/// ゲームを終了するための入力を処理します。
/// </summary>
void HandleInput()
{
  _currentKeyboardState = Keyboard.GetState();
  _currentGamePadState = GamePad.GetState(PlayerIndex.One);

  // 終了を確認します。
  if (_currentKeyboardState.IsKeyDown(Keys.Escape) ||
      _currentGamePadState.Buttons.Back == ButtonState.Pressed)
  {
    Exit();
  }
}

Získajú sa informácie o klávesnici a gamepade a určí sa koniec hry.

Metóda UpdateCamera

/// <summary>
/// カメラを動かすための入力を処理します。
/// </summary>
void UpdateCamera()
{
  const float turnSpeed = 0.05f;
  const float accelerationSpeed = 4;
  const float frictionAmount = 0.98f;

  // 左または右に曲がります。
  float turn = -_currentGamePadState.ThumbSticks.Left.X * turnSpeed;

  if (_currentKeyboardState.IsKeyDown(Keys.Left)) turn += turnSpeed;
  if (_currentKeyboardState.IsKeyDown(Keys.Right)) turn -= turnSpeed;

  _cameraForward = Vector3.TransformNormal(_cameraForward, Matrix.CreateRotationY(turn));

  // 前方または後方に加速します。
  float accel = _currentGamePadState.ThumbSticks.Left.Y * accelerationSpeed;

  if (_currentKeyboardState.IsKeyDown(Keys.Up)) accel += accelerationSpeed;
  if (_currentKeyboardState.IsKeyDown(Keys.Down)) accel -= accelerationSpeed;

  _cameraVelocity += _cameraForward * accel;

  // 現在の位置に速度を追加します。
  _cameraPosition += _cameraVelocity;

  // 摩擦力を加えます。
  _cameraVelocity *= frictionAmount;
}

Fotoaparát je ovládaný tak, aby sa mohol pohybovať.

Zahŕňa aj výpočty, ako je zrýchlenie a trenie, ale myslím si, že to pravdepodobne berie do úvahy Dopplerov efekt na 3D zvuk. Keďže na samotnom výpočte nerobím nič zvláštne, nebudem o tom diskutovať.

Súhrn

Pokryl som to dlho, ale zvyčajne to stačí na to, aby sme sa odvolávali na triedu, AudioManager ako prehrávať 3D zvuk. V skutočnosti väčšina ťažkostí je spôsobená rámcom, pretože to, čo SoundEffectInstance robíme, je nastavenie 3D informácií do . Ak ste odobrali vzorky iba časti 3D zvuku, skončíte s písaním malej práce v triede Hry. Píšem však tipy na základe pôvodného príbehu, takže to bolo oveľa dlhšie.