Audio3D

Lapa atjaunota :
Lapas izveides datums :

Piezīmes par šiem padomiem

Šis paraugs ir balstīts uz programmām, kas publicētas šādās vietnēs. Es nedaudz mainu kodu, lai būtu vieglāk to saprast un izskaidrot japāņu valodā. Būtībā mēs izmantojam sākotnējo kodu tādu, kāds tas ir, tāpēc, ja jūs to faktiski pieņemat savā spēļu programmā, savlaicīgi izlabojiet to un izmantojiet to.

Uzziņu vietne

Turklāt tas ir izskaidrots, pieņemot, ka jums ir dažas pamatzināšanas par MonoGame un XNA. Ruddly skatiet MonoGame padomus un XNA padomus .

Jo īpaši, tā kā matemātika, vektori, trigonometriskās funkcijas, matricas utt. ir būtiskas, tāpēc, lūdzu, ziniet, kādi tie zināmā mērā ir.

vide

platforma
  • Windows 10
  • Kodu var izmantot citās MonoGame iespējotās platformās
Vizuālā studija
  • Visual Studio 2019
.NET core
  • 3.1
MonoGame
  • 3.8

Par paraugiem

Pamatojoties uz kameras atrašanās vietu, jūs varat dzirdēt zvanu no suņa pozīcijas un kaķa stāvokļa. Kaķis apvelk un apriņķo izcelsmi, un spēlētājs var kontrolēt kameras pozīciju ar atslēgu. Pārliecinieties, ka skaņas dzirdēšanas veids mainās ar katru kameras stāvokļa vai kaķa stāvokļa maiņu. Es domāju, ka ir viegli saprast, izmantojot austiņas. Esmu neapstiprināts kanālā 5.1.

Kā darboties

Ko darīt tastatūras gamepad (XInput) peles pieskāriens
Kamera uz priekšu un atpakaļ ↑↓ Kreisā nūja (augšā un apakšā) - -
Kameras orientācijas maiņa ←→ Kreisā nūja (pa kreisi un pa labi) - -
Spēles beigas Esc Mugura - -

Ko sagatavot

  • Suņu squeal audio fails
  • Trīs kaķu spiedzošie audio faili
  • Suņa attēla fails
  • Kaķa attēla fails
  • Zemes attēla fails

Sākotnējā paraugā oficiālajā vietnē tiek izmantoti iepriekš izveidoti satura .xnb faili. Ja vēlaties saglabāt paraugus oficiālajā vietnē, neizmantojiet mgcbs, pievienojiet tos tieši Visual Studio risinājumam un kopējiet tos būvēšanas laikā.

Es nezinu, kāpēc sākotnējā izlase izmanto šo metodi, bet es domāju, ka tas, iespējams, ir tāpēc, ka mēs migrējam vecākas projekta versijas, kādas tās ir. Protams, jūs varat izmantot mgcb, lai ģenerētu to pašu failu. Projekti, kurus var lejupielādēt šajā vietnē, ir pārveidoti uz MGCB versiju.

programma

Lejupielādējiet programmu visam kodam.

Šis paraugs ir paredzēts, lai kods izskatītos nedaudz vispārīgāks, vienlaikus padarot skaņas atskaņošanu labu izpildlaikā. Tikai Audio3D izmantošana būtu daudz mazāka koda, bet tas ir aprakstīts kopā ar sākotnējo paraugu. Es paturēšu mazāk svarīgās daļas.

Projekts sastāv no šādiem koda failiem:

  • Audio3DGame
  • AudioManager
  • Kaķis
  • Suns
  • IAudioEmitter
  • Programma
  • QuadDrawer
  • SpriteEntity

QuadDrawer klase

Šī klase ir palīgu klase taisnstūra daudzstūru zīmēšanai. Taisnstūra daudzstūri bieži tiek izmantoti galvenokārt, lai parādītu 3D sprites (stendus). Šie padomi tiek izmantoti stendiem kaķiem un suņiem, kā arī taisnstūrveida zemes displejiem.

Šai klasei nav nekāda sakara ar Audio3D.

lauks

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

Minimālā informācija, kas nepieciešama daudzstūru zīmēšanai. Zīmējiet daudzstūrus no virsotnes datiem, nesagatavojot modeļa datus.

Konstruktors

/// <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);
}

Tā kā šī klase ir vispārēji izmantojama, jūs GraphicsDevice saņemat gadījumu, kas izveidots spēļu klases inicializācijas procesā.

Šeit mēs iestatām efektu, kas nepieciešams, lai uzzīmētu sprite un taisnstūra daudzstūrim nepieciešamo 4 virsotņu stāvokli. Zīmēšanas laikā izmērs ir jāmēro, tāpēc tas ir -1 līdz 1.

DrawQuad metode

/// <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);
}

Iestata nodoto tekstūru uz taisnstūri un zīmē to. Tā kā tas ir pamatprocess, nav ko atzīmēt.

Ja ir viens punkts, argumentā textureRepeats var norādīt izsaukto mainīgo, lai varētu mainīt faktūras koordinātas. Ja vertexPositionTexture.TextureCoordinate ir iestatīts ārpus diapazona no 0 līdz 1, tekstūra tiek zīmēta atkārtoti pēc noklusējuma. Izmantojot to, ir iespējams izteikt, ka flīzes var sakārtot atkārtoti. Faktiski rūtainajiem modeļiem uz zemes, šķiet, ir vairāki vienkārši melnbalti attēli.

IAudioEmitter interfeiss

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

Definēts kā entītija, kas izstaro skaņu. Tā kā vienības, kas šoreiz izstaro skaņu, ir suņi un kaķi, tie ir mantoti savās attiecīgajās klasēs. Emitētājam ir nepieciešama šāda informācija:

Īpašuma izmantošana
Pozīcija Entītijas pozīcija
Uz priekšu Virziens, ar kuru vienība saskaras (vektors)
Augšup Entītijas uz augšu. Virziens, kādā galva pastāv personā
Ātrums Ātrums, ar kādu entītija pārvietojas. Izmanto Doplera vērtību aprēķināšanai.

SpriteEntity klase

Klase 3D sprītu (stendu) attēlošanai. Tas ir arī emitētājs un manto IAudioEmitter . Suņi un kaķi manto šo klasi.

īpašums

/// <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; }

Tam ir informācija par vienības atrašanās vietu utt. Būtībā man kā emitētājam ir informācija. Tā ir arī zīmēšanas entītija, tāpēc tai ir arī attēls (Tekstūra), ko parādīt.

Atjaunināšanas metode

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

Apraksta entītijas atrašanās vietu un skaņas atskaņošanas procesu, bet ievieš to atvasinātajā klasē.

Zīmēšanas metode

/// <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);
}

Suņiem un kaķiem ir dažādi attēli un pozīcijas, bet otrs zīmēšanas mehānisms ir tieši tāds pats, tāpēc es tos šeit aprakstu.

Katra transformācija un tekstūra tiek nodota QuadDrawer, lai parādītu taisnstūra daudzstūri. Tā kā koordinātu transformācija ir pamatzināšanas, skaidrojumi nav ietverti.

Matrix.CreateConstrainedBillboard Izmantojiet metodes un kameras informāciju, lai viegli attēlotu informācijas stendus, tāpēc efektīvi izmantojiet tos.

Suņu klase

Tā ir klase, kas veic suņu zīmēšanu un dziedāšanu. SpriteEntity Klases mantošana. Suns paliek fiksētā stāvoklī 3D telpā.

lauks

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

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

_timeDelay tiek izmantots ar intervāliem, lai atskaņotu saucienu.

SoundEffectInstance _activeSound ir skaņas atskaņošanas gadījums. SoundEffectInstance Kā bieži redzēsiet skaņas atskaņošanas klasē, varat to izmantot tāpat kā 3D skaņās. _activeSound Starp citu , es saņemu atsauci no AudioManager klases tikai vēlāk, tāpēc es to neizmetīšu Dot klases pusē.

Atjaunināšanas metode

/// <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);
    }
  }
}

Šajā paraugā suns ilgu laiku paliek tādā pašā stāvoklī, tāpēc pirmie četri parametri ir norādīti ar izšķirošu streiku. Zīmēšana tiek veikta pamata klasē.

_timeDelay pēc tam tiek izmantots kā atlikušais laiks, lai apstātos, spēlējot saucienu.

AudioManager tiks reproducētaPlay3DSound 3D telpā, nododot kliedziena nosaukumu, cilpas informāciju un savu informāciju kā izstarotāju .

Suņu klase ir paredzēta, lai cilpotu saucienu, tāpēc jums nav jādomā pārāk dziļi, jo tā ir tikai korekcija, piemēram, spēlēšana vai sazarošanās apturēšana.

Kaķu klase

Tā ir klase, kas veic kaķu zīmēšanu un dziedāšanu. SpriteEntity Klases mantošana. Kaķis pārvietojas pa izcelsmi.

lauks

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

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

_timeDelay tiek izmantots tāpat kā suņu klase, ar pārējo laiku pirms nākamās squeal.

Ir trīs veidu kaķu zvani, kas ir nejauši izvēlēti un atskaņoti, bet tiem nav nekāda sakara ar Audio3D, jo tie ir bonusa elements.

Atjaunināšanas metode

/// <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);
  }
}

Tā kā kaķis apgriežas ap izcelsmi apļveida kustībā, tas to apstrādā tā, lai tas pārvietotu apļa trajektoriju, izmantojot trigonometrisko funkciju. Tā rezultātā pozīcija, uz priekšu un ātrums ir mainījušies viens pēc otra. Tāpēc, palaižot programmu, jūs varat redzēt, ka kaķa kliedziens riņķo apkārt pat tad, ja jūs nepārvietojat kameru.

_timeDelay Šis kods ir process, kurā kaķa kliedziens tiek nejauši piešķirts un spēlēts regulāri. audioManager.Play3DSound Es nododu sevi metodei, kas ir emitētāja. Var redzēt, ka skaņas atskaņošanas pozīcija mainās pa vienam.

AudioManager klase

Tā beidzot ir Audio3D būtība. 3D skaņa sastāv no klausītāja un izstarotāja. Izstarotājs jau definē suņus un kaķus, tāpēc AudioManager klase definē klausītājus. Parasti ir vairāki emitētāji, bet ir tikai viens klausītājs.

Šī klase pārmanto unGame reģistrē GameComponent un izmanto klases komponentu.

ActiveSound klase

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

Tas ir definēts koda apakšā, bet tā ir klase, lai saglabātu stāvokli, kas spēlē. Tajā ir informācija par atskaņoto skaņas instanci un atskaņoto emitētāju.

lauks

// このマネージャーにロードされるすべてのサウンドエフェクトのリスト。
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 definē ielādējamā audio faila nosaukumu (līdzekļa nosaukumu). Tā kā tā ir programmas paraugs, vispirms ir definēts, ka audio fails tiek ielādēts lielapjomā. Importētie skaņas dati tiek _soundEffects glabāti programmā .

AudioListener Listener ir klausītāja definīcija. Klausītāja informācija ir definēta, jo tā public ir iestatīta no spēles klases.

AudioEmitter _emitter ir izstarotāja definīcija, lietojot 3D skaņas atskaņošanai. Šajā paraugā, atskaņojot skaņu, katra izstarotāja objekta vērtība ir iestatīta uz _emitter , tāpēc tā ir forma, kas to parasti dala. Protams, jums var būt par katru AudioEmitter objektu.

_activeSounds ir informācija par skaņu, ko atskaņojat iepriekš definētajā ActiveSound klasē. Tā kā izstarotāja informācija visu laiku mainās, to izmanto, lai atjauninātu atrašanās vietas informāciju utt., kā arī atmestu skaņas gadījumus, kas ir beiguši atskaņošanu.

Konstruktors

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

GameComponent Tā kā tā manto klasi, Game tā saņem gadījumu un nodod to pamatklasei.

Inicializēt metodi

/// <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 Tā kā tā manto klasi, tā tiek automātiski izsaukta inicializācijas laikā.

SoundEffect.DistanceScale un SoundEffect.DopplerScale ir parametri, kas veltīti 3D skaņai static .

SoundEffect.DistanceScale dzirdēt skaņu pat tālumā.

SoundEffect.DopplerScale ir Doplera efekta ietekme. Jo lielāks skaitlis, jo lielāks ir Doplera efekts.

_soundNames Saglabājiet cilpā definēto līdzekļa nosaukumu , lai ielādētu _soundEffects .

Iznīcināšanas metode

/// <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 Tas tiek automātiski izsaukts spēles beigās, jo tas manto klasi.

Iznīcinot visus importētos skaņas aktīvus.

Atjaunināšanas metode

/// <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 Tā kā tā pārmanto klasi, tā tiek automātiski izsaukta atjaunināšanas procesā.

Pārbaudiet pašlaik atskaņoto skaņu un, ja tā Apply3D tiek atskaņota, zvaniet uz skaņas atrašanās vietas atjaunināšanas metodi, lai tā atbilstu izstarotājam. Ja kāda skaņa ir beigusi atskaņot, instance tiek atmesta.

Play3DSound metode

/// <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;
}

3D skaņas atskaņošanas process no ārpuses. Tam ir atskaņotās skaņas nosaukums, vai cilpa un izstarot informāciju.

Ja vēlaties atskaņot skaņu, izveidojiet jaunu skaņas instanci no skaņas resursa, ko glabājat _soundEffects. SoundEffectInstance var būt arī cilpa vai nē, tāpēc iestatiet cilpas informāciju.

Tā kā es radu kā ActiveSound atskaņošanas stāvokli, es iestatīju izstarotāja informāciju, kas tur ir skaņas atskaņošanas objekts. Ja vēlaties skaņai lietot 3D atrašanās vietas informāciju, jūs Emitter saņemsiet nepieciešamo vērtību.

Apply3D Metode ir aprakstīta turpmāk, bet tas ir process, kā skaņai tiek piemērota 3D informācija no izstarotāja.

3D skaņas pamatprocess ir sākt atskaņošanu ar SoundEffectInstance.Play 3D informācijas kopu. Pārējais ir periodiski atjaunināt 3D informāciju, līdz skaņa ir pabeigta.

Apply3D metode

/// <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);
}

3D efekta piemērošanas process noteiktai skaņas instancei, izmantojot klausītājus un izstarotājus.

Mēs katru reizi nosakām vērtību kopējās instances _emitter. Ja jums SoundEffectInstance.Apply3D tāds jau AudioEmitter ir, vienkārši nododiet klausītāju un izstarotāju metodei.

Audio3DGame klase

Visbeidzot, apskatīsim, par ko ir Spēles klase.

lauks

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 Reģistrējas GameComponents , bet vai tas ir kā lauks, jo tas piekļūst tam individuāli.

Citi definē suņu, kaķu vienības, tekstūras zemes zīmēšanai, kvadriciklu, kameras informāciju un ievades informāciju.

Konstruktors

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 Ģenerēt un GameComponents reģistrēties programmā .

Jūs esat ģenerējis arī kaķu un suņu nodarbības.

LoadContent metode

/// <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);
}

Ielādējiet katram zīmējumam nepieciešamās faktūras.

QuadDrawer šeit tiek GraphicsDevice ģenerēts , jo nepieciešams .

Atjaunināšanas metode

/// <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 Metodes un UpdateCamera metodes ir ierīces ievades un kameras apstrādes process, kas tiks apspriests vēlāk.

Tā kā kameras novietojums un klausītāja pozīcija gandrīz vienmēr ir vienāda, klausītājam pēc kameras atjaunināšanas procesa ir iestatīta vienāda vērtība.

_cat Zvaniet uz un _dog atjauniniet metodes, lai attiecīgi pārvietotos un izspiestu.

Zīmēšanas metode

/// <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);
}

Ģenerē skata un projekcijas transformācijas no kameras informācijas.

Zemei QuadDrawer zīmētais taisnstūris tiek parādīts vertikāli, tāpēc tas tiek pagriezts tā, lai tas būtu horizontāls un mēreni palielināts. _quadDrawer.DrawQuad Metodes otrais arguments norāda tekstūras atkārtojumu skaitu, kas norāda, ka 32x32 loksnes parādās blakus.

_cat un _dog tiek izvietoti iekšējās informācijas stendā, tāpēc kameras atrašanās vietas informācija tiek nodota un zīmēta.

Metode HandleInput

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

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

Tiek iegūta informācija uz tastatūras un gamepad, un tiek noteiktas spēles beigas.

UpdateCamera metode

/// <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;
}

Kamera tiek kontrolēta, lai pārvietotos.

Tas ietver arī tādus aprēķinus kā paātrinājums un berze, bet es domāju, ka tas, iespējams, ņem vērā Doplera ietekmi uz 3D skaņu. Tā kā es nedaru neko īpašu attiecībā uz pašu aprēķinu, es to neapspriedīšu.

Kopsavilkuma

Esmu to ilgi nosedzis, bet parasti pietiek ar to, ka klasei ir jāatsaucas uz AudioManager to, kā atskaņot 3D skaņu. Patiesībā lielāko daļu grūtību veic sistēma, jo tas, ko SoundEffectInstance mēs darām, ir 3D informācijas iestatīšana . Ja esat atlasījis tikai tās 3D skaņas daļas, jūs galu galā rakstāt nelielu darbu spēļu klasē. Tomēr es rakstu Padomus, pamatojoties uz sākotnējo stāstu, tāpēc tas ir bijis daudz ilgāks.