Audio3D

Lehekülg uuendatud :
Lehe loomise kuupäev :

Märkused selle näpunäite kohta

See valim põhineb järgmistel saitidel avaldatud programmidel. Ma muudan koodi veidi, et seda oleks lihtsam jaapani keeles mõista ja selgitada. Põhimõtteliselt kasutame algset koodi nii, nagu see on, nii et kui te selle oma mänguprogrammis tegelikult vastu võtate, parandage see õigeaegselt ja kasutage seda.

Viitesait

Lisaks selgitatakse eeldust, et teil on mõned põhiteadmised MonoGame'i ja XNA kohta. Vaadake monogame näpunäiteid ja XNA näpunäiteid ruddly jaoks.

Eelkõige, kuna matemaatika, vektorid, trigonomeetrilised funktsioonid, maatriksid jne on olulised, siis palun teadke, mis need on mingil määral.

keskkond

platvorm
  • Windows 10
  • Koodi saab kasutada ka teistel MonoGame'i toega platvormidel
Visual Studio
  • Visual Studio 2019
.NET Core
  • 3.1
MonoGame
  • 3.8

Näidistest

Kaamera asukoha põhjal saate kõnet kuulda koera asendist ja kassi asendist. Kass tiirleb ümber ja tiirleb ümber päritolu ning mängija saab võtmega kontrollida kaamera asendit. Veenduge, et heli kuulmine muutub iga kaamera asukoha või kassi asukoha muutusega. Ma arvan, et kõrvaklappide abil on seda lihtne mõista. Ma ei ole kanalil 5.1 kinnitatud.

Kuidas toimida?

Mida teha klaviatuuri gamepad (XInput) hiire puudutus
Kaamera edasi ja tagasi ↑↓ Vasak kepp (ülemine ja alumine) - -
Kaamera orientatsiooni muutmine ←→ Vasak kepp (vasak ja parem) - -
Mängu lõpp Esc Tagasi - -

Mida ette valmistada

  • Koera piiksuv helifail
  • Kolm kassi piiksuvat helifaili
  • Koera pildifail
  • Kassi pildifail
  • Maapealne pildifail

Ametliku saidi algne proov kasutab eelehitatud sisu .xnb faile. Kui soovite proove ametlikul saidil hoida, ärge kasutage mgcb-e, lisage need otse visual studio lahendusse ja kopeerige need ehitamise ajal.

Ma ei tea, miks algne proov seda meetodit kasutab, aga ma arvan, et see on ilmselt sellepärast, et me migreerime projekti vanemaid versioone. Loomulikult saate sama faili loomiseks kasutada mgCB-d. Projektid, mida saab sellel saidil alla laadida, on muudetud MGCB versiooniks.

programm

Laadige programm alla kogu koodi jaoks.

See proov on loodud selleks, et muuta kood veidi üldisemaks, muutes heli taasesituse käitusajal hea välja. Ainult Audio3D-i kasutamine oleks palju vähem koodi, kuid seda kirjeldatakse algses proovis. Ma jätan vähem tähtsad osad endale.

Projekt koosneb järgmistest koodifailidest:

  • Audio3DGame
  • AudioManager
  • Kass
  • Koer
  • IAudioEmitter
  • Programm
  • QuadDrawer
  • SpriteEntity

QuadDrawer klass

See klass on abistajaklass ristkülikukujuliste hulknurkade joonistamiseks. Ristkülikukujulisi hulknurki kasutatakse sageli peamiselt 3D-sprite (stendide) kuvamiseks. Neid näpunäiteid kasutatakse kasside ja koerte stendide, samuti ristkülikukujuliste maapinna kuvarite jaoks.

Sellel klassil pole audio3D-ga midagi pistmist.

põld

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

Minimaalne teave, mis on vajalik hulknurkade joonistamiseks. Joonistage tipuandmetest hulknurgad ilma mudeliandmeid koostamata.

ehitaja

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

Kuna see klass on universaalselt kasutatav, saate GraphicsDevice mänguklassi lähtestamisprotsessis loodud eksemplari.

Siin määrame efekti, mis on vajalik spriidi joonistamiseks ja ristkülikukujulise polügooni jaoks vajaliku nelja tipu asukohaks. Joonistamisel tuleks suurust skaleerida, nii et see on -1 kuni 1.

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

Määrab läbitud tekstuuri ristkülikuks ja joonistab selle. Kuna see on põhiprotsess, pole midagi märkida.

Kui on üks punkt, saab argumendis textureRepeats määrata muutuja nimega muutuja, nii et tekstuuri koordinaate saab muuta. Kui vertexPositionTexture.TextureCoordinate on seatud väljapoole vahemikku 0 kuni 1, joonistatakse tekstuur vaikimisi korduvalt. Selle abil on võimalik väljendada, et plaate saab korduvalt paigutada. Tegelikult tundub, et maapinnal olevatel ruudulistel mustritel on mitu lihtsat mustvalget pilti.

IAudioEmitter liides

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

Määratletakse kui üksust, mis kiirgab heli. Kuna seekord heli eraldavad üksused on koerad ja kassid, päritakse nad oma vastavates klassides. Emitter vajab järgmist teavet:

Atribuudi kasutamine
Asend Olemi positsioon
Edasi Suund, millega üksus silmitsi seisab (vektor)
Üles Olevuse üles. Suund, milles pea inimeses eksisteerib
Kiirus Kiirus, millega üksus liigub. Kasutatakse Doppleri väärtuste arvutamiseks.

Klass SpriteEntity

Klass 3D-sprite (stendide) esindamiseks. See on ka emitter ja pärib IAudioEmitter . Koerad ja kassid pärivad selle klassi.

vara

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

Sellel on üksuse asukohateave jne. Põhimõtteliselt on mul infot emitterina. See on ka joonistusolem, seega on sellel kuvamiseks ka pilt (tekstuur).

Värskendamise meetod

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

Kirjeldab olemi positsiooni ja heli esitamise protsessi, kuid rakendab seda tuletatud klassis.

Joonistamise meetod

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

Koertel ja kassidel on erinevad pildid ja positsioonid, kuid teine joonistusmehhanism on täpselt sama, nii et ma kirjeldan neid siin.

Iga transformatsioon ja tekstuur edastatakse QuadDrawerile ristkülikukujulise polügooni kuvamiseks. Kuna koordinaatide teisendamine on põhiteadmised, ei ole selgitused hõlmatud.

Matrix.CreateConstrainedBillboard Kasutage stendide hõlpsaks esitamiseks meetodit ja kaamerateavet, nii et kasutage neid tõhusalt.

Koeraklass

See on klass, mis teeb koera joonistamist ja laulmist. SpriteEntity Klassi pärimine. Koer jääb fikseeritud asendisse 3D-ruumis.

põld

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

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

_timeDelay seda kasutatakse intervallidega, et mängida nutmist.

SoundEffectInstance _activeSound See on näide heli esitamisest. SoundEffectInstance Nagu heli taasesituse klassis sageli näete, saate seda kasutada nii, nagu see on 3D-helis. Muide _activeSound , ma saan ainult viite AudioManageri klassist hiljem, nii et ma ei viska seda dot klassi poolel.

Värskendamise meetod

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

Selles proovis jääb koer pikka aega samasse asendisse, nii et esimesed neli parameetrit on määratud otsustava löögiga. Joonistamine toimub põhiklassis.

_timeDelay kasutatakse siis järelejäänud ajana, et lõpetada, mängides nutmist.

AudioManager reprodutseeritaksePlay3DSound 3D-ruumis, edastades hüüde nime, silmusteabe ja oma teabe emitterina .

Koeraklass on mõeldud nutma, nii et te ei pea liiga sügavalt mõtlema, sest see on lihtsalt kohandamine, näiteks mängimine või hargnemise peatamine.

Kassiklass

See on klass, mis teeb kassi joonistamist ja taasesituse laulmist. SpriteEntity Klassi pärimine. Kass liigub päritolu ümber.

põld

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

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

_timeDelay seda kasutatakse samamoodi nagu koeraklassi, ülejäänud aja jooksul enne järgmist piiksu.

Juhuslikult valitud ja mängitud kassikõnesid on kolme tüüpi, kuid neil pole audio3D-ga midagi pistmist, sest need on boonuselement.

Värskendamise meetod

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

Kuna kass pöörab päritolu ringikujuliselt ümber, töötleb ta seda nii, et see liigutab ringi trajektoori trigonomeetrilise funktsiooni abil. Selle tulemusena on positsioon, edasi ja kiirus üksteise järel muutunud. Seega, kui käivitate programmi, näete, et kassi nutt tiirleb ringi isegi siis, kui te kaamerat ei liiguta.

_timeDelay Järgmine kood on protsess, kus kassi nutt määratakse juhuslikult ja mängitakse regulaarselt. audioManager.Play3DSound Ma lähen üle meetodile, mis on emitter. Näete, et heli taasesitusasend muutub ükshaaval.

AudioManageri klass

See on lõpuks Audio3D olemus. 3D-heli koosneb kuulajast ja emitterist. Emitter määratleb juba koerad ja kassid, nii et AudioManageri klass määratleb kuulajad. Tavaliselt on mitu emitterit, samas kui kuulajaid on ainult üks.

See klass pärib jaGame registreerib GameComponent ning kasutab klassi komponenti.

ActiveSound klass

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

See on määratletud koodi allosas, kuid see on klass mängiva riigi säilitamiseks. Sellel on teavet esitatava helieksemplari ja emitteri mängimise kohta.

põld

// このマネージャーにロードされるすべてのサウンドエフェクトのリスト。
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 määratleb laaditava helifaili nime (vara nimi). Kuna tegemist on näidisprogrammiga, on määratletud esmalt helifaili hulgilaadimine. Imporditud heliandmed salvestatakse _soundEffects rakendusse .

AudioListener Listener See on kuulaja definitsioon. Kuulaja teave on määratletud, kuna see public on seatud mänguklassist.

AudioEmitter _emitter on emitteri määratlus 3D rakendamisel heli taasesitusele. Selles proovis on heli esitamisel iga emitteri objekti väärtuseks _emitter seatud , nii et see on vorm, mis jagab seda eksemplarina. Loomulikult võib teil olla iga AudioEmitter objekti jaoks.

_activeSounds sisaldab teavet heli kohta, mida esitate varem määratletud ActiveSound klassis. Kuna emitteri teave muutub kogu aeg, kasutatakse seda asukohateabe jms värskendamiseks ja esitamise lõpetanud helieksemplari hülgamiseks.

ehitaja

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

GameComponent Kuna see pärib klassi, Game saab ta eksemplari ja edastab selle baasklassile.

Lähtestamise meetod

/// <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 Kuna see pärib klassi, kutsutakse see lähtestamisel automaatselt.

SoundEffect.DistanceScale ja SoundEffect.DopplerScale on 3D-helile static pühendatud parameetrid.

SoundEffect.DistanceScale Kuulda heli isegi kauguses.

SoundEffect.DopplerScale See on Doppleri efekti mõju. Mida suurem on see arv, seda suurem on Doppleri efekt.

_soundNames Salvestage laaditavas _soundEffects silmuses määratletud vara nimi .

Käsuta meetod

/// <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 See kutsutakse automaatselt mängu lõpus, sest see pärib klassi.

Kõigi imporditud helivarade hävitamine.

Värskendamise meetod

/// <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 Kuna see pärib klassi, kutsutakse see värskendusprotsessis automaatselt.

Kontrollige praegu esitatavat heli ja kui seda Apply3D esitatakse, helistage meetodile, et värskendada heli asukohta, et see vastaks emitterile. Kui mõni heli on esitamise lõpetanud, visatakse eksemplar ära.

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

3D-heli mängimine väljastpoolt. Sellel on esitatava heli nimi, kas silmus ja emitteri teave.

Kui soovite esitada heli, looge _soundEffects olevast heliressursist uus helieksemplar. SoundEffectInstance võib olla ka silmus või mitte, nii et seadke silmuse teave.

Kuna ma loon mänguolekuna ActiveSound , määran emitteri teabe, mis on seal heli taasesitusobjekt. Kui soovite helile rakendada 3D-asukohateavet, saate Emitter vajaliku väärtuse.

Apply3D Meetodit kirjeldatakse allpool, kuid see on 3D-teabe rakendamine emitterist helile.

3D-heli põhiprotsess on taasesituse alustamine 3D-teabekomplektiga SoundEffectInstance.Play . Ülejäänud on 3D-teabe perioodiline värskendamine, kuni heli on esitamise lõpetanud.

Rakenda3D-meetod

/// <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-efekti rakendamine määratud helieksemplarile, kasutades kuulajaid ja emittereid.

Me määrame väärtuseks ühise eksemplari _emitter iga kord. Kui teil SoundEffectInstance.Apply3D on see juba AudioEmitter olemas, andke lihtsalt kuulaja ja emitter meetodile.

Audio3DGame klass

Vaatame lõpuks, mida mänguklass endast kujutab.

põld

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 Registreerub GameComponents rakenduses , kuid tal on see väljana, kuna see pääseb sellele eraldi juurde.

Teised määratlevad koera, kassi olemid, maapinna joonistamise tekstuurid, nelinurk, kaamera teave ja sisendteave.

ehitaja

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 Saate luua ja GameComponents registreeruda rakenduses .

Olete loonud ka kassi ja koera klassid.

LoadContent meetod

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

Laadige iga joonise jaoks vajalikud tekstuurid.

QuadDrawer on GraphicsDevice loodud siin, sest nõuab .

Värskendamise meetod

/// <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 Meetodid ja UpdateCamera meetodid on seadme sisendi toomise ja kaamera käsitsemise protsess, mida arutatakse hiljem.

Kuna kaamera asukoht ja kuulaja asend on peaaegu alati samad, on kuulaja pärast kaamera uuendamise protsessi seatud samale väärtusele.

_cat Helistage vastavalt teisaldamiseks ja _dog piiksumiseks meetodeid ja värskendage meetodeid.

Joonistamise meetod

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

Loob kaamera teabest vaate- ja projektsioonimuundumised.

Maapinna jaoks kuvatakse QuadDraweris joonistatud ristkülik vertikaalselt, nii et seda pööratakse horisontaalseks ja suurendatakse mõõdukalt. _quadDrawer.DrawQuad Meetodi teine argument määrab tekstuuri korduste arvu, mis määrab, et kõrvuti kuvatakse 32x32 lehte.

_cat ja _dog on stenditud sisemiselt, nii et kaamera asukohateave edastatakse ja joonistatakse.

HandleInput meetod

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

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

Teave klaviatuuril ja gamepadil omandatakse ning määratakse mängu lõpp.

UpdateCamera meetod

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

Kaamerat juhitakse liikuma.

See sisaldab ka arvutusi, nagu kiirendus ja hõõrdumine, kuid ma arvan, et see võtab tõenäoliselt arvesse Doppleri efekti 3D-helile. Kuna ma ei tee arvutuse enda suhtes midagi erilist, siis ma seda ei aruta.

Kokkuvõte

Olen selle pikalt katnud, kuid tavaliselt piisab, kui viidata klassile AudioManager , kuidas mängida 3D-heli. Tegelikult teeb enamik raskusi raamistik, sest see, mida SoundEffectInstance me teeme, on 3D-teabe seadmine . Kui olete proovinud ainult 3D-heli osi, kirjutate mänguklassis väikese töö. Kuid ma kirjutan näpunäiteid, mis põhinevad algsel lool, nii et see on olnud palju pikem.