Un piccolo serpente ci conduce attraverso le principali caratteristiche del Windows Phone 7
Introduzione Core UI & Design Conclusione Premi Discussioni
Marcosroom.it Didatticando

Audio & XNA

Un'ultima cosa prima di iniziare: dobbiamo ricordarci che stiamo sviluppando un'applicazione Silverlight, quindi, per utilizzare XNA, dobbiamo fare qualche passo di preparazione. Se scrivi un'applicazione XNA da zero, non devi fare nulla, ma se vuoi far sì che XNA e Silverlight lavorino insieme all'interno della stessa applicazione Silverlight, è sufficiente un piccolo trucco. Eccolo: XNA è un grande framework, con molti oggetti, e chi sa cosa c'è dietro quello che vediamo! Ma una cosa è sicura: XNA ha bisogno che i suoi messaggi interni vengano processati. XNA è in grado di farlo autonomamente, se l'applicazione è scritta interamente per XNA, ma questo non è il nostro caso, quindi, cosa possiamo fare? Semplice: dobbiamo scrivere una classe che processi i messaggi del framework XNA! Fortunatamente, esiste il metodo Microsoft.Xna.Framework.FrameworkDispatcher.Update, che elabora i messaggi per noi, quindi, tutto ciò che dobbiamo fare è chiamare regolarmente questo metodo.

public class XNAAsyncDispatcher : IApplicationService
{
    private DispatcherTimer frameworkDispatcherTimer;

    public XNAAsyncDispatcher(TimeSpan dispatchInterval)
    {
        this.frameworkDispatcherTimer = new DispatcherTimer();
        this.frameworkDispatcherTimer.Tick += new EventHandler(frameworkDispatcherTimer_Tick);
        this.frameworkDispatcherTimer.Interval = dispatchInterval;
    }

    void IApplicationService.StartService(ApplicationServiceContext context) { 
        this.frameworkDispatcherTimer.Start(); 
    }
    void IApplicationService.StopService() { 
        this.frameworkDispatcherTimer.Stop(); 
    }

    void frameworkDispatcherTimer_Tick(object sender, EventArgs e) {
        Microsoft.Xna.Framework.FrameworkDispatcher.Update(); 
    }
}


public partial class App : Application
{
    public App()
    {
        // ...
        // Enables the XNA Async Dispatcher
        this.ApplicationLifetimeObjects.Add(new XNAAsyncDispatcher(TimeSpan.FromMilliseconds(50)));
        // ...
    }
}

(Se non sai cos'è un application lifetime object, ti consiglio di leggere questo piccolo post di Shawn Wildermuth: The Application Class and Application Services in Silverlight 3)

Quindi, questo è il codice. Nel costruttore del nostro dispatcher (XNAAsyncDispatcher) creiamo un DispatcherTimer il quale chiama il metodo FrameworkDispatcher.Update. Null'altro, questo è il dispatcher. L'ultimo passo è aggiungerlo all'insieme dei lifetime objects, quindi, nel costruttore della classe App, aggiungiamo un nuovo XNAAsyncDispatcher alla lista ApplicationLifetimeObjects.

Bene... ora che XNA è pronto a darci il massimo, possiamo iniziare!

Ciò che dobbiamo fare prima, è sapere che tutto l'audio che abbiamo può essere diviso in canzoni ed effetti sonori: i primi sono un pezzo musicale continuo, mentre i secondi sono dei brevi suoni riprodotti in momenti specifici. Per esempio, una canzone è la musica di sottofondo di un gioco, mentre un effetto sonoro è il rumore riprodotto quando il serpente mangia del cibo.

Quando iniziamo ad utilizzare il framework XNA per riprodurre la musica, dobbiamo fare attenzione a seguire le Windows Phone 7 Application Certification Requirements.

6.5.1 Initial Launch Functionality

When the user is already playing music on the phone when the application is launched, the application must not pause, resume, or stop the active music in the phone MediaQueue by calling the Microsoft.Xna.Framework.Media.MediaPlayer class.

If the application plays its own background music or adjusts background music volume, it must ask the user for consent to stop playing/adjust the background music (e.g. message dialog or settings menu).

This requirement does not apply to applications that play sound effects through the Microsoft.Xna.Framework.Audio.SoundEffect class, as sound effects will be mixed with the MediaPlayer. The SoundEffect class should not be used to play background music.

In poche parole, bisognerebbe controllare che l'utente non stia già riproducendo della musica, altrimenti, bisognerebbe chiedergli il consenso di fermare la sua musica e di riprodurre quella dell'applicazione. Un altro punto importante è che gli effetti sonori dovrebbero essere riprodotti come effetti sonori, perchè la musica non può essere mixata, mentre più effetti possono essere riprodotti contemporaneamente.

Come controllare se l'utente sta già riproducendo della musica? Se Microsoft.Xna.Framework.Media.MediaPlayer.GameHasControl è true, puoi riprodurre la tua musica, poichè l'utente non sta ascoltando nulla; se è false, dovresti chiedergli il consenso per interrompere la musica di sottofondo. Comunque, ne vedremo successivamente un esempio.

Se abbiamo due differenti classificazioni per l'audio, avremo due differenti modi di gestione: per riprodurre canzoni, useremo l'oggetto Song, e er gli effetti sonori SoundEffect. Risiedono entrambi nel namespace Microsoft.Xna.Framework.Audio e Microsoft.Xna.Framework.Media, ma prima di tutto, dobbiamo aggiungere un riferimento al principale assembly dell'intero XNA framework Microsoft.Xna.Framework.dll:

Adding a reference to Microsoft.Xna.Framework.dll

Un'altra cosa importante da fare è preparare i file audio: devono essere in formato WAV per funzionare con XNA, anche se MP3 è supportato dall'oggetto Song (non da SoundEffect). L'ultima cosa è che, in Visual Studio, dobbiamo impostare la proprietà Build Action del file audio su Content.

Ma ora è giunto il momento di lasciare che sia il codice a parlare:

//Loads a song
Song song = Song.FromUri("BackgroundMusic", new Uri("Sounds/Music.wav", UriKind.RelativeOrAbsolute));

//Loads a sound effect
SoundEffect soundEffect = SoundEffect.FromStream(TitleContainer.OpenStream("Sounds/Death.wav"));

Per creare una Song da un file, chiamiamo il metodo static FromUri dell'oggetto Song; il primo parametro è il nome della canzone, mentre il secondo è l'Uri del file, relativo al pacchetto XAP (ricorda che abbiamo impostato Build Action su Content). Per caricare un SoundEffect, invece, chiamiamo il metodo statico FromStream della classe SoundEffect; il parametro è lo stream che contiene il file audio. TitleContainer.OpenStream restituisce uno stream che punta ad un file all'interno del pacchetto XAP.

Una volta che abbiamo creato i nostri oggetti, dobbiamo riprodurli, no? Per riprodurre un SoundEffect, è sufficiente chiamare il suo metodo Play; mentre per riprodurre una Song abbiamo bisogno di un media player, quindi, dobbiamo chiamare MediaPlayer.Play e passare come parametro il nostro oggetto Song.

//Riproduce la canzone
MediaPlayer.Play(song);

//Riproduce l'effetto sonoro
soundEffect.Play();

Tornando alla nostra applicazione, la classe responsabile della gestione dei suoni è SnakeMobile.Core.Sounds:

Sounds class

Le 3 proprietà sono i percorsi dei nostri file audio (relativi al pacchetto XAP). Queste proprietà vengono inizializzate all'interno del file App.xaml.cs:

public partial class App : Application
{
    public App()
    {
        // ...
        //Sounds
        SnakeMobile.Core.Sounds.BackgroundMusicUri = new Uri("Sounds/Music.wav", UriKind.RelativeOrAbsolute);
        SnakeMobile.Core.Sounds.DeathSoundPath = "Sounds/Death.wav";
        SnakeMobile.Core.Sounds.EatSoundPath = "Sounds/Eat.wav";
        // ...

    }
}

Gli altri metodi, invece, sono divisi in due categorie: PlayBackgroundMusic e StopBackgroundMusic sono usati, come dice il nome, per riprodurre e arrestare la musica di sottofondo; PlayEffect, invece, riproduce un singolo effetto sonoro.

public static void PlayBackgroundMusic() {

    //Checks if sound is enabled
    if (Settings.Settings.Instance.Sound == false)
        return;

    //Plays the song
    if (BackgroundMusicUri != null && MediaPlayer.GameHasControl) {
        MediaPlayer.IsRepeating = true;
        MediaPlayer.Play(Song.FromUri("BackgroundMusic", BackgroundMusicUri));
    }

}

Per esempio, analizziamo PlayBackgroundMusic (gli altri sono molto simili): la prima cosa da fare è controllare che l'utente abbia abilitato i suoni all'interno del gioco o se li ha disabilitati attraverso la pagina Settings. Poi controlliamo che l'utente non stia riproducendo una sua musica di sottofondo (MediaPlayer.GameHasControl); a questo punto, possiamo riprodurre la canzone, ed abilitare la riproduzione.

 

Condividi
Indietro Tutti i webmaster che volessero segnalare, non copiare,
il contenuto di questa pagina sul proprio sito, possono farlo liberamente.
E' gradito un preavviso tramite mail all'autore e l'iserimento,
nella pagina di citazione, di un link verso la pagina corrente.
© Copyright    Marco's Room
Avanti
Download SnakeMobile

Scaricato 115 volte

Navigazione Transizioni Pulsante rotondo luminoso Trigger Un piccolo ripasso di matematica Selettore circolare Isolated storage: file e impostazioni Impostazioni Build action: Content o Resource? Audio & XNA