Ääni3D
Huomautuksia näistä vinkeistä
Tämä esimerkki perustuu seuraavissa sivustoissa julkaistuihin ohjelmiin. Muutan koodia hieman, jotta se olisi helpompi ymmärtää ja selittää japaniksi. Periaatteessa käytämme alkuperäistä koodia sellaisenaan, joten jos todella otat sen käyttöön peliohjelmassasi, korjaa se ajoissa ja käytä sitä.
Lisäksi se selitetään olettamuksella, että sinulla on jonkin verran perustietoa MonoGamesta ja XNA: sta. Katso MonoGame-vinkit ja XNA-vinkit ruddlylle.
Erityisesti matematiikka, vektorit, trigonometriset toiminnot, matriisit jne., Ovat välttämättömiä, joten tiedä, mitä ne ovat jossain määrin.
ympäristö
- lava
-
- Windows 10
- Koodia voidaan käyttää muilla MonoGame-yhteensopivilla alustoilla
- Visual Studio
-
- Visual Studio 2019
- .NET-ydin
-
- 3.1
- MonoGame
-
- 3.8
Tietoja näytteistä
Kameran sijainnin perusteella voit kuulla kutsun koiran sijainnista ja kissan sijainnista. Kissa ympyröi ja ympyröi alkuperän, ja pelaaja voi hallita kameran sijaintia avaimella. Varmista, että äänen kuuleminen muuttuu jokaisen kameran sijainnin tai kissan sijainnin muutoksen myötä. Mielestäni on helppo ymmärtää kuulokkeiden avulla. Minua ei ole vahvistettu kanavalla 5.1.
Miten toimia
Mitä tehdä | näppäimistön | peliohjain (XInput) | Hiiren | kosketus |
---|---|---|---|---|
Kamera eteen- ja taaksepäin | ↑↓ | Vasen sauva (ylä- ja alaosa) | - | - |
Kameran suunnan muuttaminen | ←→ | Vasen sauva (vasen ja oikea) | - | - |
Pelin loppu | Esc | Selkä | - | - |
Mitä valmistaa
- Koiran squeal äänitiedosto
- Kolme kissan vinkumista äänitiedostoa
- Koiran kuvatiedosto
- Kissan kuvatiedosto
- Maadoituskuvatiedosto
Alkuperäinen näyte virallisella sivustolla käyttää valmiiksi rakennettuja sisältöjä .xnb tiedostoja. Jos haluat säilyttää näytteet virallisella sivustolla, älä käytä mgcbs: ää, lisää ne suoraan Visual Studio -ratkaisuusi ja kopioi ne rakennushetkellä.
En tiedä, miksi alkuperäinen näyte käyttää tätä menetelmää, mutta luulen, että se johtuu todennäköisesti siitä, että siirrämme projektin vanhempia versioita sellaisenaan. Voit tietysti käyttää mgcb: tä saman tiedoston luomiseen. Projektit, jotka voidaan ladata tältä sivustolta, on muutettu MGCB-versioon.
ohjelma
Lataa ohjelma kaikille koodeille.
Tämä näyte on suunniteltu saamaan koodi näyttämään hieman yleisemmältä ja samalla saamaan äänen toisto näyttämään hyvältä suorituksen aikana. Vain Audio3D: n käyttäminen olisi paljon vähemmän koodia, mutta se on kuvattu alkuperäisessä näytteessä. Pidän vähemmän tärkeät osat.
Projekti koostuu seuraavista kooditiedostoista:
- Audio3DGame
- AudioManager
- Kissa
- Koira
- IAudioEmitter
- Ohjelma
- QuadDrawer
- SpriteEntity
QuadDrawer-luokka
Tämä luokka on avustajaluokka suorakulmaisten monikulmioiden piirtämiseen. Suorakulmaisia monikulmioita käytetään usein ensisijaisesti 3D-spritien (mainostaulujen) näyttämiseen. Näitä vinkkejä käytetään kissojen ja koirien mainostauluihin sekä maan suorakulmaisiin näyttöihin.
Tällä luokalla ei ole mitään tekemistä Audio3D: n kanssa.
pelto
readonly GraphicsDevice _graphicsDevice;
readonly AlphaTestEffect _effect;
readonly VertexPositionTexture[] _vertices;
Monikulmioiden piirtämiseen tarvitaan vähimmäistiedot. Piirrä monikulmioita kärkipistetiedoista valmistelematta mallitietoja.
rakentaja
<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);
}
Koska tämä luokka on yleisesti käyttökelpoinen, saat GraphicsDevice
esiintymän, joka on luotu peliluokan alustusprosessissa.
Tässä asetamme tarvittavan vaikutuksen spriten piirtämiseksi ja suorakulmaisen monikulmion edellyttämien 4 kärkipisteen sijainnin piirtämiseksi. Koko on skaalattava piirtämisen aikana, joten se on -1 - 1.
DrawQuad-menetelmä
<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äärittää välitetyn materiaalikuvion suorakulmioksi ja piirtää sen. Koska tämä on perusprosessi, ei ole mitään huomautettavaa.
Jos argumentissa textureRepeats
on yksi piste, muuttuja, jota kutsutaan, voidaan määrittää, jotta tekstuurin koordinaatteja voidaan muuttaa.
Jos vertexPositionTexture.TextureCoordinate on asetettu alueen 0 - 1 ulkopuolelle, materiaalikuvio piirretään oletusarvoisesti toistuvasti.
Sen avulla on mahdollista ilmaista, että laatat voidaan järjestää toistuvasti.
Itse asiassa maassa olevilla ruudullisilla kuvioilla näyttää olevan useita yksinkertaisia mustavalkoisia kuvia.
IAudioEmitter-käyttöliittymä
<summary>
3D サウンドを再生するエンティティの位置と速度を検索するために AudioManager が使用するインターフェイス。
</summary>
public interface IAudioEmitter
{
Vector3 Position { get; }
Vector3 Forward { get; }
Vector3 Up { get; }
Vector3 Velocity { get; }
}
Määritetty entiteetiksi, joka säteilee ääntä. Koska tällä kertaa ääntä lähettävät entiteetit ovat koiria ja kissoja, ne periytyvät omissa luokissaan. Emitter tarvitsee seuraavat tiedot:
Ominaisuuden | käyttö |
---|---|
Asema | Entiteetin toimi |
Eteenpäin | Entiteetin suunta (vektori) |
Ylös | Entiteetin nousu. Suunta, jossa pää on henkilössä |
Nopeus | Nopeus, jolla entiteetti liikkuu. Käytetään Doppler-arvojen laskemiseen. |
SpriteEntity-luokka
Luokka, joka edustaa 3D-sprittejä (mainostauluja). Se on myös emitteri ja perii IAudioEmitter
.
Koirat ja kissat perivät tämän luokan.
ominaisuus
<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; }
Sillä on yksikön sijaintitiedot jne. Periaatteessa minulla on tietoa päästöjen aiheuttajana. Se on myös piirustusentiteetti, joten siinä on myös kuva (pintakuvio) näytettäväksi.
Päivitä-menetelmä
<summary>
エンティティの位置を更新し、サウンドを再生できるようにします。
</summary>
public abstract void Update(GameTime gameTime, AudioManager audioManager);
Kuvaa entiteetin sijainnin ja äänen toistoprosessin, mutta toteuttaa sen johdetussa luokassa.
Piirrä menetelmä
<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);
}
Koirilla ja kissoilla on erilaiset kuvat ja asennot, mutta toinen piirustusmekanismi on täsmälleen sama, joten kuvailen niitä täällä.
Jokainen muunnos ja rakenne välitetään QuadDrawerille suorakulmaisen monikulmion näyttämiseksi. Koska koordinaattimuunnos on perustietoa, selityksiä ei käsitellä.
Matrix.CreateConstrainedBillboard
Käytä menetelmä- ja kameratietoja edustamaan mainostauluja helposti, joten käytä niitä tehokkaasti.
Koiraluokka
Se on luokka, joka tekee koiran piirtämistä ja laulamista. SpriteEntity
Luokan periminen.
Koira pysyy kiinteässä asennossa 3D-tilassa.
pelto
<summary>サウンドを開始または停止するまでの時間。</summary>
TimeSpan _timeDelay = TimeSpan.Zero;
<summary>現在再生中のサウンド(ある場合)。</summary>
SoundEffectInstance _activeSound = null;
_timeDelay
käytetään säännöllisin väliajoin itkun toistamiseen.
SoundEffectInstance _activeSound
on esimerkki äänen toistamisesta.
SoundEffectInstance
Kuten usein näet äänen toistoluokassa, voit käyttää tätä sellaisenaan 3D-äänessä.
Muuten _activeSound
, saan viittauksen AudioManager-luokasta vain myöhemmin, joten en hylkää sitä Dot-luokan puolella.
Päivitä-menetelmä
<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);
}
}
}
Tässä näytteessä koira pysyy samassa asennossa pitkään, joten neljä ensimmäistä parametria määritetään ratkaisevalla iskulla. Piirustus tehdään perusluokassa.
_timeDelay käytetään sitten jäljellä olevana ajankohtana pysähtyä, soittamalla huutoa.
AudioManager
toistetaanPlay3DSound
3D-tilassa välittämällä itkun nimi, silmukan tiedot ja omat tietosi lähettimenä -järjestelmään.
Koira-luokka on suunniteltu silmukkaan itku, joten sinun ei tarvitse ajatella liian syvälle, koska se on vain säätö, kuten pelaaminen tai haarautumisen lopettaminen.
Kissan luokka
Se on luokka, joka piirtää kissaa ja laulaa toistoa. SpriteEntity
Luokan periminen.
Kissa liikkuu alkuperän ympärillä.
pelto
<summary>次の音を鳴らすまでの時間。</summary>
TimeSpan _timeDelay = TimeSpan.Zero;
<summary>サウンドバリエーションから選択するための乱数ジェネレータ。</summary>
static readonly Random _random = new Random();
_timeDelay
käytetään samalla tavalla kuin Koira-luokkaa, ja loput ajasta ennen seuraavaa vinkumista.
On olemassa kolmenlaisia kissakutsuja, jotka valitaan satunnaisesti ja toistetaan, mutta niillä ei ole mitään tekemistä Audio3D: n kanssa, koska ne ovat bonuselementti.
Päivitä-menetelmä
<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);
}
}
Koska kissa kääntyy alkuperän ympäri pyöreällä liikkeellä, se käsittelee sitä niin, että se siirtää ympyrän liikerataa trigonometrisellä toiminnolla. Tämän seurauksena sijainti, eteenpäin ja Nopeus ovat muuttuneet yksi toisensa jälkeen. Siksi, kun suoritat ohjelman, voit nähdä, että kissan itku kiertää ympäri, vaikka et siirrä kameraa.
_timeDelay
Seuraava koodi on prosessi, jossa kissan itku osoitetaan satunnaisesti ja pelataan säännöllisin väliajoin.
audioManager.Play3DSound
Siirryn menetelmään, joka on päästöjen aiheuttaja.
Voit nähdä, että äänen toistoasento muuttuu yksitellen.
AudioManager-luokka
Tämä on vihdoin Audio3D: n ydin. 3D-ääni koostuu kuuntelijasta ja säteilijästä. Emitteri määrittelee jo koirat ja kissat, joten AudioManager-luokka määrittelee kuuntelijat. Säteilijöitä on yleensä useita, kun taas kuuntelijoita on vain yksi.
Tämä luokka perii,Game
rekisteröi GameComponent
ja käyttää luokan komponenttia.
ActiveSound-luokka
<summary>
アクティブな3Dサウンドを追跡し、アタッチされているエミッターオブジェクトを記憶するための内部ヘルパークラス。
</summary>
private class ActiveSound
{
public SoundEffectInstance Instance;
public IAudioEmitter Emitter;
}
Se on määritelty koodin alaosassa, mutta se on luokka pelaavan tilan säilyttämiseksi. Siinä on tietoa toistettavasta ääniesiintymästä ja toistettavasta emitteristä.
pelto
// このマネージャーにロードされるすべてのサウンドエフェクトのリスト。
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äärittää ladattavan äänitiedoston nimen (resurssin nimen). Koska se on esimerkkiohjelma, äänitiedosto on määritetty lataamaan ensin joukkona.
Tuodut äänitiedot tallennetaan _soundEffects
-järjestelmään.
AudioListener Listener
on kuuntelijan määritelmä. Kuuntelijan tiedot määritetään -järjestelmässä, koska ne public
on määritetty Peli-luokasta.
AudioEmitter _emitter
on lähettimen määritelmä, kun 3D:tä käytetään äänentoistoon.
Tässä esimerkissä ääntä toistettaessa kunkin lähetinobjektin arvoksi _emitter
määritetään , joten se on lomake, joka jakaa yhden esiintymänä.
Tietenkin voit saada jokaiselle AudioEmitter
esineelle.
_activeSounds
sisältää tietoja äänestä, jota toistat aiemmin määrittämässäsi ActiveSound
luokassa.
Koska lähetintiedot muuttuvat koko ajan, sitä käytetään sijaintitietojen päivittämiseen jne., Ja hylkäämään toiston lopettaneet ääniesiintymät.
rakentaja
public AudioManager(Game game) : base(game) { }
GameComponent
Koska se perii luokan, Game
se vastaanottaa esiintymän ja välittää sen perusluokkaan.
Alusta menetelmä
<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
Koska se perii luokan, sitä kutsutaan automaattisesti alustuksen yhteydessä.
SoundEffect.DistanceScale
ja SoundEffect.DopplerScale
ovat parametreja, jotka on omistettu 3D-äänelle static
.
SoundEffect.DistanceScale
kuulla ääntä jopa etäisyydellä.
SoundEffect.DopplerScale
on Doppler-vaikutuksen vaikutus. Mitä suurempi luku, sitä suurempi doppler-vaikutus.
_soundNames
Tallenna silmukassa määritetty resurssin nimi lataamista _soundEffects
varten .
Hävittämismenetelmä
<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
Sitä kutsutaan automaattisesti pelin lopussa, koska se perii luokan.
Tuhoan kaikki tuodut äänivarat.
Päivitä-menetelmä
<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
Koska se perii luokan, sitä kutsutaan automaattisesti päivitysprosessissa.
Tarkista toistettava ääni ja, jos sitä Apply3D
toistetaan, soita menetelmään päivittääksesi äänen sijainnin vastaamaan lähetintä.
Jos jonkin äänen toistaminen on päättynyt, esiintymä hylätään.
Play3DSound-menetelmä
<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;
}
Prosessi, jossa 3D-ääntä toistetaan ulkopuolelta. Siinä on toistettavan äänen nimi, olipa kyseessä silmukka ja säteilevä tieto.
Jos haluat toistaa äänen, luo uusi ääniesiintymä _soundEffects säilytettävästä ääniresurssista.
SoundEffectInstance
voi olla myös silmukka tai ei, joten aseta silmukan tiedot.
Koska luon toistotilana ActiveSound
, asetan lähetintiedot, jotka ovat siellä olevan äänen toisto-objekti.
Jos haluat käyttää 3D-sijaintitietoja äänessä, saat Emitter
tarvitsemasi arvon.
Apply3D
Menetelmä on kuvattu alla, mutta se on prosessi, jossa 3D-tietoja levitetään säteilijästä ääneen.
3D-äänen perusprosessi on aloittaa toisto 3D-tietojoukolla SoundEffectInstance.Play
.
Loput on päivittää 3D-tiedot säännöllisesti, kunnes ääni on toistettu.
Apply3D-menetelmä
<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);
}
Prosessi, jossa 3D-tehostetta käytetään määritettyyn ääni-esiintymään kuuntelijoiden ja säteilijöiden avulla.
Asetamme arvon yleisen esiintymän _emitter joka kerta.
Jos sinulla SoundEffectInstance.Apply3D
on jo AudioEmitter
sellainen, siirrä vain kuuntelija ja lähetin menetelmään.
Audio3DGame-luokka
Lopuksi katsotaanpa, mistä Peli-luokassa on kyse.
pelto
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
Rekisteröityy GameComponents
-järjestelmään, mutta pitää sitä kenttänä, koska se käyttää sitä erikseen.
Toiset määrittelevät koiran, kissan entiteetit, maapiirustuksen tekstuurit, quaddrawerin, kameratiedot ja syöttötiedot.
rakentaja
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
Luo ja GameComponents
rekisteröi -toiminnolla .
Olet myös luonut Kissa ja koira -luokat.
LoadContent-menetelmä
<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);
}
Lataa kuhunkin piirustukseen tarvittavat pintakuviot.
QuadDrawer
luodaan GraphicsDevice
tässä, koska se vaatii .
Päivitä-menetelmä
<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
Menetelmät ja UpdateCamera
menetelmät ovat prosessi laitteen tulon hakemiseksi ja kameran käsittelemiseksi, josta keskustellaan myöhemmin.
Koska kameran sijainti ja kuuntelijan sijainti ovat lähes aina samat, kuuntelija asetetaan samaan arvoon kameran päivitysprosessin jälkeen.
_cat
Voit siirtää ja vinkua valitsemalla - ja _dog
Päivitä-menetelmiä.
Piirrä menetelmä
<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);
}
Luo näkymä- ja projektiomuunnokset kameran tiedoista.
Maassa QuadDrawerissa piirretty suorakulmio näytetään pystysuunnassa, joten sitä kierretään vaakasuoraksi ja suurennetaan kohtalaisesti.
_quadDrawer.DrawQuad
Menetelmän toinen argumentti määrittää tekstuurin toistojen määrän, mikä määrittää, että 32x32 arkkia näkyy vierekkäin.
_cat ja _dog mainostetaan sisäisesti, joten kameran sijaintitiedot välitetään ja piirretään.
HandleInput-menetelmä
<summary>
ゲームを終了するための入力を処理します。
</summary>
void HandleInput()
{
_currentKeyboardState = Keyboard.GetState();
_currentGamePadState = GamePad.GetState(PlayerIndex.One);
// 終了を確認します。
if (_currentKeyboardState.IsKeyDown(Keys.Escape) ||
_currentGamePadState.Buttons.Back == ButtonState.Pressed)
{
Exit();
}
}
Näppäimistön ja peliohjaimen tiedot hankitaan, ja pelin loppu määritetään.
UpdateCamera-menetelmä
<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;
}
Kameraa ohjataan liikkumaan.
Se sisältää myös laskelmia, kuten kiihtyvyyttä ja kitkaa, mutta luulen, että se todennäköisesti ottaa huomioon Doppler-vaikutuksen 3D-ääneen. Koska en tee mitään erityistä itse laskelmalle, en keskustele siitä.
Yhteenveto
Olen peittänyt sen pitkään, mutta yleensä riittää, että viittaat luokkaan AudioManager
3D-äänen toistamiseksi.
Itse asiassa suurin osa vaikeuksista tapahtuu kehyksellä, koska teemme SoundEffectInstance
3D-tietojen asettamisen .
Jos olet ottanut näytteitä vain 3D-äänen osista, päädyt kirjoittamaan pienen työn Peli-luokkaan.
Kirjoitan kuitenkin vinkkejä alkuperäisen tarinan perusteella, joten siitä on paljon kauemmin.