tag:blogger.com,1999:blog-15114685277595993882024-03-13T01:07:27.833-07:00Imparando XNAIn questo blog vengono presentate alcune veloci guide per imparare ad utilizzare XNA. I tutorial saranno completamente scritti in qualcosa di molto simile all'italiano :P, presentando quando necessario una video anteprima e codici sorgenti.Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.comBlogger19125tag:blogger.com,1999:blog-1511468527759599388.post-9026867108241707622010-06-23T05:36:00.000-07:002010-06-23T05:48:55.142-07:00Pausa...Ciao a tutti!<br />come avrete notato il blog è fermo da un pò di mesi...Al momento sono totalmente assorbito dal lavoro e da altri progetti, quindi mi risulta impossibile continuare a studiare e scrivere argomenti legati a XNA. Lo dico veramente a malincuore, perchè lo studio di XNA mi ha veramente divertito e vedere che le visite sul blog aumentavano di settimana in settimana è stato senza dubbio motivo di profonda soddisfazione.<br /><br />Non è un addio, perchè non si può mai sapere, ma sono sicuro che non mi cimenterò più su XNA per un pò. Per ora scriverò unicamente per <a href="http://www.yariok.com">http://www.yariok.com</a> (programmazione web).<br /><br />Grazie veramente tanto a tutti quelli che hanno seguito il blog fino ad ora, spero che possa comunque essere utile per chi vuole imparare le basi di XNA da zero e per chi ha bisogno di ripassare alcuni argomenti!<br /><br />Ciao a tutti e grazie ancora<br />YariYari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com1tag:blogger.com,1999:blog-1511468527759599388.post-73726423004151160912010-02-13T10:19:00.000-08:002011-10-05T00:42:47.685-07:003D.5c) XNA Tutorial 3d: HLSL shader in XNA - Specular lightCiao a tutti! rieccomi dopo il solito mesetto di silenzio! -.-<br />Prima di partire con il post di oggi ci terrei a segnalare <a href="http://www.indievault.it/">IndieVault.it</a> e relativo <a href="http://www.indievault.it/forum/">Forum</a> attraverso il quale mi è tornata la voglia di lavorare un pò su XNA! Ci tengo a segnalarlo perchè è una delle poche realtà Italiane che tratta l'argomento XNA e dintorni (Aggiungo anche <a href="http://forum.xnaitalia.com/">XNAitalia</a>) fateci un salto! non ve ne pentirete.<br /><br />Il post di oggi tratterà L'illuminazione Speculare, ovvero la capacità di un materiale di essere "Lucido", e quindi di riflettere la luce proveniente da una sorgente luminosa relativamente alla posizione dell'osservatore.<br /><br />Da questa breve descrizione spiccano quindi 3 elementi:<br /><br />1) un oggeto<br />2) una fonte di luce<br />3) un osservatore<br /><br />La differenza rispetto agli shader visti fino ad ora è dunque la presenza di un osservatore, o meglio, il fatto che la sua posizione sia determinante per definire in che modo si comporti lo shader.<br />Prima di proseguire vi mostro il video di quanto andremo a sviluppare:<br /><object height="385" width="480"><param name="movie" value="http://www.youtube.com/v/3bCBrwligZE&hl=it_IT&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/3bCBrwligZE&hl=it_IT&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" height="385" width="480"></embed></object><br /><br />Dal video potete notare come il riflesso cambi posizione e forma in base al movimento della camera.Per capire come codificare questo effetto dobbiamo prima analizzarlo e capire come i vari attori descritti sopra interagiscono tra di loro:<br /><br />Nell'immagine qui sotto sono presenti 5 elementi:<br />1) Vettore osservatore (dal'osservatore verso la superficie)<br />2) Vettore Luce (Direzione della luce diffuse)<br />3) Vettore Riflesso (Creato dal "rimbalzo" del vettore luce sulla superficie)<br />4) Normale della superficie<br />5) Angolo Alpha compreso tra l'osservatore e il riflesso<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheAo2bG_CffRFmupwK0Esg2vmd6OUgIy7gHq9UV3eI_vEa3Vgm1k7922wBjnWeQUDQByk_Uyv1X5kQELIQ8LUj_vCCBAWEdV5sQbpU13psov3m0rA6UTlHQX5UIrk1A8lFQhzl8VJ2MFQ/s1600-h/specular_light.jpg"><img style="cursor: pointer; width: 400px; height: 267px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEheAo2bG_CffRFmupwK0Esg2vmd6OUgIy7gHq9UV3eI_vEa3Vgm1k7922wBjnWeQUDQByk_Uyv1X5kQELIQ8LUj_vCCBAWEdV5sQbpU13psov3m0rA6UTlHQX5UIrk1A8lFQhzl8VJ2MFQ/s400/specular_light.jpg" alt="" id="BLOGGER_PHOTO_ID_5439346943038532258" border="0" /></a><br /><br /><span style="font-weight: bold;">Il valore di luce speculare</span> presente nel punto di incidenza dei vettori visti sopra <span style="font-weight: bold;">varia in base all'angolo alpha, </span> al crescere di alpha diminuisce e viceversa quanto più alpha tende a zero tanto più la luce speculare aumenta. In pratica portando il vettore dell'osservatore in concidenza del vettore riflesso la luce speculare sarà massima.<br /><br />Passiamo al <span style="font-weight: bold;">codice HLSL:</span><br /><pre><span style="color: rgb(255, 102, 51);"><span style="font-weight: bold;">//0*********************************************************</span></span><br />float4x4 World<b><span style="color: rgb(102, 51, 0);">;</span></b><br />float4x4 View<b><span style="color: rgb(102, 51, 0);">;</span></b><br />float4x4 Projection<b><span style="color: rgb(102, 51, 0);">;</span></b><br />float4x4 WorldInverseTranspose<b><span style="color: rgb(102, 51, 0);">;</span></b><br /><br />float4 AmbientColor<b><span style="color: rgb(102, 51, 0);"> =</span></b> float4<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">);</span></b><span style="color: rgb(255, 102, 51);"><br />float</span> AmbientIntensity<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 102, 0);"> 0.2</span><b><span style="color: rgb(102, 51, 0);">;</span></b><br /><br />float3 DiffuseLightDirection<b><span style="color: rgb(102, 51, 0);"> =</span></b> float3<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">);</span></b><br />float4 DiffuseColor<b><span style="color: rgb(102, 51, 0);"> =</span></b> float4<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">);</span></b><span style="color: rgb(255, 102, 51);"><br />float</span> DiffuseIntensity<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 102, 0);"> 1.0</span><b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(255, 102, 51);"><br /></span><span style="font-weight: bold;">float3 ViewVector</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0); font-weight: bold;"><br /></span><br /><span style="color: rgb(255, 102, 51);"><span style="font-weight: bold;">//1*********************************************************</span><br />float</span> Shininess<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);"> 30</span><b><span style="color: rgb(102, 51, 0);">;</span></b><br />float4 SpecularColor<b><span style="color: rgb(102, 51, 0);"> =</span></b> float4<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">);</span></b><span style="color: rgb(255, 102, 51);"><br />float</span> SpecularIntensity<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 102, 0);"> 0.3</span><b><span style="color: rgb(102, 51, 0);">;</span></b><br /><span style="color: rgb(153, 0, 0);"><br /><br /></span><span style="color: rgb(255, 102, 51);"><span style="font-weight: bold;">//2*********************************************************</span></span><br /><br /><span style="color: rgb(153, 0, 0);">struct</span> VertexShaderInput<b><span style="color: rgb(102, 51, 0);"><br />{</span></b><br />float4 Position<b><span style="color: rgb(102, 51, 0);"> :</span></b> POSITION0<b><span style="color: rgb(102, 51, 0);">;</span></b><br />float4 Normal<b><span style="color: rgb(102, 51, 0);"> :</span></b> NORMAL0<b><span style="color: rgb(102, 51, 0);">;<br />};</span></b><span style="color: rgb(153, 0, 0);"><br /><br />struct</span> VertexShaderOutput<b><span style="color: rgb(102, 51, 0);"><br />{</span></b><br />float4 Position<b><span style="color: rgb(102, 51, 0);"> :</span></b> POSITION0<b><span style="color: rgb(102, 51, 0);">;</span></b><br />float4 Color<b><span style="color: rgb(102, 51, 0);"> :</span></b> COLOR0<b><span style="color: rgb(102, 51, 0);">;</span></b><br /><b style="font-weight: bold;"> float3 Normal<span style="color: rgb(102, 51, 0);"> :</span></b><span style="font-weight: bold;"> TEXCOORD0</span><b><span style="color: rgb(102, 51, 0);"><span style="font-weight: bold;">;</span><br />};</span></b><br /><br /><span style="color: rgb(255, 102, 51);"><span style="font-weight: bold;">//3*********************************************************</span></span><br /><br />VertexShaderOutput VertexShaderFunction<b><span style="color: rgb(102, 51, 0);">(</span></b>VertexShaderInput input<b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><br />VertexShaderOutput output<b><span style="color: rgb(102, 51, 0);">;</span></b><br /><br />float4 worldPosition<b><span style="color: rgb(102, 51, 0);"> =</span></b> mul<b><span style="color: rgb(102, 51, 0);">(</span></b>input<b><span style="color: rgb(102, 51, 0);">.</span></b>Position<b><span style="color: rgb(102, 51, 0);">,</span></b> World<b><span style="color: rgb(102, 51, 0);">);</span></b><br />float4 viewPosition<b><span style="color: rgb(102, 51, 0);"> =</span></b> mul<b><span style="color: rgb(102, 51, 0);">(</span></b>worldPosition<b><span style="color: rgb(102, 51, 0);">,</span></b> View<b><span style="color: rgb(102, 51, 0);">);</span></b><br />output<b><span style="color: rgb(102, 51, 0);">.</span></b>Position<b><span style="color: rgb(102, 51, 0);"> =</span></b> mul<b><span style="color: rgb(102, 51, 0);">(</span></b>viewPosition<b><span style="color: rgb(102, 51, 0);">,</span></b> Projection<b><span style="color: rgb(102, 51, 0);">);</span></b><br />float4 normal<b><span style="color: rgb(102, 51, 0);"> =</span></b> normalize<b><span style="color: rgb(102, 51, 0);">(</span></b>mul<b><span style="color: rgb(102, 51, 0);">(</span></b>input<b><span style="color: rgb(102, 51, 0);">.</span></b>Normal<b><span style="color: rgb(102, 51, 0);">,</span></b> WorldInverseTranspose<b><span style="color: rgb(102, 51, 0);">));</span></b><span style="color: rgb(255, 102, 51);"><br />float</span> lightIntensity<b><span style="color: rgb(102, 51, 0);"> =</span></b> dot<b><span style="color: rgb(102, 51, 0);">(</span></b>normal<b><span style="color: rgb(102, 51, 0);">,</span></b> DiffuseLightDirection<b><span style="color: rgb(102, 51, 0);">);</span></b><br />output<b><span style="color: rgb(102, 51, 0);">.</span></b>Color<b><span style="color: rgb(102, 51, 0);"> =</span></b> saturate<b><span style="color: rgb(102, 51, 0);">(</span></b>DiffuseColor<b><span style="color: rgb(102, 51, 0);"> *</span></b> DiffuseIntensity<b><span style="color: rgb(102, 51, 0);"> *</span></b> lightIntensity<b><span style="color: rgb(102, 51, 0);">);</span></b><br /><br /><b style="font-weight: bold;">output<span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Normal</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> normal</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(255, 0, 0);"><br /><br />return</span> output<b><span style="color: rgb(102, 51, 0);">;<br />}</span></b><br /><br /><span style="color: rgb(255, 102, 51);"><span style="font-weight: bold;">//4*********************************************************</span></span><br /><br />float4 PixelShaderFunction<b><span style="color: rgb(102, 51, 0);">(</span></b>VertexShaderOutput input<b><span style="color: rgb(102, 51, 0);">) :</span></b> COLOR0<b><span style="color: rgb(102, 51, 0);"><br />{</span></b><br />float3 light<b><span style="color: rgb(102, 51, 0);"> =</span></b> normalize<b><span style="color: rgb(102, 51, 0);">(</span></b>DiffuseLightDirection<b><span style="color: rgb(102, 51, 0);">);</span></b><br />float3 normal<b><span style="color: rgb(102, 51, 0);"> =</span></b> normalize<b><span style="color: rgb(102, 51, 0);">(</span></b>input<b><span style="color: rgb(102, 51, 0);">.</span></b>Normal<b><span style="color: rgb(102, 51, 0);">);</span></b><br /><span style="font-weight: bold;"> float3 r</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> normalize</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0); font-weight: bold;">2</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> *</span></b><span style="font-weight: bold;"> dot</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">light</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> normal</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">) *</span></b><span style="font-weight: bold;"> normal</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> -</span></b><span style="font-weight: bold;"> light</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><br /><span style="font-weight: bold;"> float3 v</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> normalize</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">mul</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">normalize</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">ViewVector</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="font-weight: bold;"> World</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">));</span></b><span style="color: rgb(255, 102, 51); font-weight: bold;"><br />float</span><span style="font-weight: bold;"> dotProduct</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> dot</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">r</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> v</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><br /><br /><b> float4 specular<span style="color: rgb(102, 51, 0);"> =</span></b> SpecularIntensity<b><span style="color: rgb(102, 51, 0);"> *</span></b> SpecularColor<b><span style="color: rgb(102, 51, 0);"> *</span></b> max<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">pow</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">dotProduct</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> Shininess</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">) *</span></b> length<b><span style="color: rgb(102, 51, 0);">(</span></b>input<b><span style="color: rgb(102, 51, 0);">.</span></b>Color<b><span style="color: rgb(102, 51, 0);">);</span></b><span style="color: rgb(255, 0, 0);"><br /><br />return</span> saturate<b><span style="color: rgb(102, 51, 0);">(</span></b>input<b><span style="color: rgb(102, 51, 0);">.</span></b>Color<b><span style="color: rgb(102, 51, 0);"> +</span></b> AmbientColor<b><span style="color: rgb(102, 51, 0);"> *</span></b> AmbientIntensity<b><span style="color: rgb(102, 51, 0);"> +</span></b> specular<b><span style="color: rgb(102, 51, 0);">);<br />}</span></b><br /><br /><span style="color: rgb(255, 102, 51);"><span style="font-weight: bold;">//5*********************************************************</span></span><br />technique Specular<b><span style="color: rgb(102, 51, 0);"><br />{</span></b><br />pass Pass1<b><span style="color: rgb(102, 51, 0);"><br />{</span></b><br /> VertexShader<b><span style="color: rgb(102, 51, 0);"> =</span></b> compile vs_1_1 VertexShaderFunction<b><span style="color: rgb(102, 51, 0);">();</span></b><br /> PixelShader<b><span style="color: rgb(102, 51, 0);"> =</span></b> compile ps_2_0 PixelShaderFunction<b><span style="color: rgb(102, 51, 0);">();<br />}<br />}</span></b><br /><br /></pre>Come per gli altri post, ho diviso il codice in macro aree<br /><span style="font-weight: bold;">0)Definizione della variabili </span><br />In questo blocco definiamo le informazioni che riguardano le matrici (world view projection) e le luci Ambient e Diffuse (se non sapete cosa siano, seguite i due post precedenti nell'area 3d dal menu a destra) .<br />Come voce nuova vediamo invece <span style="font-weight: bold;">ViewVector</span> che identifica il vettore osservatore.<br /><br /><span style="font-weight: bold;">1)Definizione della luce speculare<br /></span><span style="font-style: italic;">Shininess: </span> Lucidezza (più è alto più piccola sarà il riflesso sulla superficie)<span style="font-weight: bold;"><br /></span><span style="font-style: italic;">SpecularColor:</span> Colore della luce<br /><span style="font-style: italic;">SpecularIntensity:</span> Quantità di specularità( più è alto più la luce viene riflessa)<span style="font-weight: bold;"><br /><br /></span><span style="font-weight: bold;">2)Definizione delle strutture VS input e VS Output<br /></span>Da notare soltanto che al VS output aggiungiamo il valore della normale del vertice. Che è appunto la normale segnata nell'immagine sopra.<span style="font-weight: bold;"><br /><br />3) VertexShader<br /></span>E quindi nel vertexshader aggiungiamo in output l'informazione relativa alla normale del vertice.<span style="font-weight: bold;"><br /></span><br /><span style="font-weight: bold;">4) PixelShader </span><br />Tramite il pixel shader andiamo ad effettuare tutti i calcoli necessari per determinare la luce per i vari pixel. Dopo aver normalizzato i vettori light e normal calcoliamo il vettore riflesso <span style="font-weight: bold; font-style: italic;">"r"</span> che rappresenta la freccia verde nell'immagine sopra e il vettore <span style="font-weight: bold;">"v"</span> che rappresenta la posizione dell'osservatore (nella scena).<br />Ora attraverso il prodotto <span style="font-weight: bold;">dot</span> calcoliamo la quantità presente tra i due vettori (alpha) e possiamo quindi calcolare il valore specular elevando il <span style="font-weight: bold;">dotProduct</span> al valore di <span style="font-weight: bold;">Shininess</span> e poi moltiplicando per gli altri fattori che definisco la nostra luce speculare.<br /><br />Le formule presenti nel punto 4 non sono assolutamente banali, e comunque non di immediata comprensione, l'importante è capire almeno quali siano gli elementi che fanno variare la luce speculare e in che modo.<br /><br /><br />Per quanto riguarda il codice di game1.cs invece è necessario soffermarsi solo su piccoli aspetti:<br /><pre><span style="color: rgb(153, 0, 0);"> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)<br /> {</span></b><i><span style="color: rgb(153, 153, 153);"><br /> //Opzioni per la camera<br /></span></i> GamePadState gamePadState<b><span style="color: rgb(102, 51, 0);"> =</span></b> GamePad<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">(</span></b>PlayerIndex<b><span style="color: rgb(102, 51, 0);">.</span></b>One<b><span style="color: rgb(102, 51, 0);">);</span></b><br /> MouseState mouseState<b><span style="color: rgb(102, 51, 0);"> =</span></b> Mouse<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">();</span></b><br /> KeyboardState keyState<b><span style="color: rgb(102, 51, 0);"> =</span></b> Keyboard<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">();</span></b><br /> fpsCam<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>mouseState<b><span style="color: rgb(102, 51, 0);">,</span></b> keyState<b><span style="color: rgb(102, 51, 0);">,</span></b> gamePadState<b><span style="color: rgb(102, 51, 0);">);</span></b><br /><br /> world<b><span style="color: rgb(102, 51, 0);"> =</span></b> Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>Identity<b><span style="color: rgb(102, 51, 0);"> *</span></b> Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>CreateRotationY<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">0</span><b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);"><br /><br /><span style="font-weight: bold;"> //Da usare per lo shader specular</span><br /></span></i><span style="font-weight: bold;"> viewVector</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> fpsCam</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">cameraPosition</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><br /><span style="font-weight: bold;"> viewVector</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Normalize</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();</span></b><br /><br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);<br /> }<br /><br /></span></b></pre>Nella funzione Update aggiungiamo le informazioni relative alla posizione della camera (osservatore).<br /><br /><pre><i><span style="color: rgb(153, 153, 153);">//Funzione per utilizzare lo shader specular<br /></span></i><span style="color: rgb(153, 0, 0);">private</span><span style="color: rgb(255, 102, 51);"> void</span> DrawModelSpecular<b><span style="color: rgb(102, 51, 0);">(</span></b>Model model<b><span style="color: rgb(102, 51, 0);">,</span></b> Matrix world<b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><br /> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>ModelMesh mesh in model<b><span style="color: rgb(102, 51, 0);">.</span></b>Meshes<b><span style="color: rgb(102, 51, 0);">)<br /> {</span></b><br /> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>ModelMeshPart part in mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>MeshParts<b><span style="color: rgb(102, 51, 0);">)<br /> {</span></b><br /> part<b><span style="color: rgb(102, 51, 0);">.</span></b>Effect<b><span style="color: rgb(102, 51, 0);"> =</span></b> effect<b><span style="color: rgb(102, 51, 0);">;</span></b><br /><br /> worldInverseTransposeMatrix<b><span style="color: rgb(102, 51, 0);"> =</span></b> Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>Transpose<b><span style="color: rgb(102, 51, 0);">(</span></b>Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>Invert<b><span style="color: rgb(102, 51, 0);">(</span></b>mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>ParentBone<b><span style="color: rgb(102, 51, 0);">.</span></b>Transform<b><span style="color: rgb(102, 51, 0);"> *</span></b> world<b><span style="color: rgb(102, 51, 0);">));</span></b><br /> effect<b><span style="color: rgb(102, 51, 0);">.</span></b>Parameters<b><span style="color: rgb(102, 51, 0);">[</span></b><span style="color: rgb(0, 153, 0);">"WorldInverseTranspose"</span><b><span style="color: rgb(102, 51, 0);">].</span></b>SetValue<b><span style="color: rgb(102, 51, 0);">(</span></b>worldInverseTransposeMatrix<b><span style="color: rgb(102, 51, 0);">);</span></b><br /> <b style="font-weight: bold;">effect<span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Parameters</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[</span></b><span style="font-weight: bold; color: rgb(0, 153, 0);">"ViewVector"</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">].</span></b><span style="font-weight: bold;">SetValue</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">viewVector</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><br /><br /> effect<b><span style="color: rgb(102, 51, 0);">.</span></b>Parameters<b><span style="color: rgb(102, 51, 0);">[</span></b><span style="color: rgb(0, 153, 0);">"World"</span><b><span style="color: rgb(102, 51, 0);">].</span></b>SetValue<b><span style="color: rgb(102, 51, 0);">(</span></b>world<b><span style="color: rgb(102, 51, 0);"> *</span></b> mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>ParentBone<b><span style="color: rgb(102, 51, 0);">.</span></b>Transform<b><span style="color: rgb(102, 51, 0);"> );</span></b><br /> effect<b><span style="color: rgb(102, 51, 0);">.</span></b>Parameters<b><span style="color: rgb(102, 51, 0);">[</span></b><span style="color: rgb(0, 153, 0);">"View"</span><b><span style="color: rgb(102, 51, 0);">].</span></b>SetValue<b><span style="color: rgb(102, 51, 0);">(</span></b>fpsCam<b><span style="color: rgb(102, 51, 0);">.</span></b>ViewMatrix<b><span style="color: rgb(102, 51, 0);">);</span></b><br /> effect<b><span style="color: rgb(102, 51, 0);">.</span></b>Parameters<b><span style="color: rgb(102, 51, 0);">[</span></b><span style="color: rgb(0, 153, 0);">"Projection"</span><b><span style="color: rgb(102, 51, 0);">].</span></b>SetValue<b><span style="color: rgb(102, 51, 0);">(</span></b>fpsCam<b><span style="color: rgb(102, 51, 0);">.</span></b>ProjectionMatrix<b><span style="color: rgb(102, 51, 0);">);<br /> }</span></b><br /> mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">();<br /> }<br />}</span></b><b><span style="color: rgb(102, 51, 0);"></span></b></pre>Mentre nella funzione draw chiameremo la funzione DrawModelSpecular dove richiameremo l'effetto passando il nuovo parametro<span style="font-weight: bold;"> ViewVector</span>.<br /><br /><span style="font-weight: bold;">Fonte:</span><br /><a href="http://rbwhitaker.wikidot.com/specular-lighting-shader">http://rbwhitaker.wikidot.com/specular-lighting-shader</a><br /><br /><span style="font-weight: bold;">Sorgenti:</span><br /><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.5specular.hlsl.zip">imparandoxna_3d.5specular.hlsl.zip</a>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com3tag:blogger.com,1999:blog-1511468527759599388.post-34614405027953393262009-11-06T06:01:00.001-08:002011-10-05T00:51:34.588-07:00TwitXNA<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg85b7piszS1_LCpMTCjpYVVSIrMZFgVugr812JXyElf4fJ6dCF56IZbqoEBdxSuH4QzXOn6hpc8-Xvf_4PO8MpvpO1lJ-_XDz4kN8pix7uNcecrf-JpAKQnuiV7BeA2bgE9zwp0X1i5U4/s1600-h/Twitter-Logo.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 189px; height: 189px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg85b7piszS1_LCpMTCjpYVVSIrMZFgVugr812JXyElf4fJ6dCF56IZbqoEBdxSuH4QzXOn6hpc8-Xvf_4PO8MpvpO1lJ-_XDz4kN8pix7uNcecrf-JpAKQnuiV7BeA2bgE9zwp0X1i5U4/s400/Twitter-Logo.png" alt="" id="BLOGGER_PHOTO_ID_5400991791015408930" border="0" /></a><br />Ciao A tutti,<br />Vi segnalo <a href="http://www.thinkandbuild.it/twitxna">http://www.thinkandbuild.it/twitxna</a>, un mini progetto che sto curando (è più che altro un esperimento).<br />Si tratta di una pagina web che raccoglie le discussioni di Twitter relative a XNA. L'idea è partita giusto per provare le API di twitter, ma in realtà mi sono reso conto che è interessante vedere come nel resto del mondo la gente sia più avanti sul discorso XNA :P. C'è un gran via vai di informazioni e ogni tanto si trova qualche tutorial interessante difficilmetne reperibile con Google.<br /><br />La pagina viene aggiornata automaticamente, lasciate scorrere le notizie fino a quando non spariscono in dissolvenza.. quando meno di 3/4 news sono presenti nell'area ne vengono ricaricate altre. Per ora è ancora un esperimento fatto in due serate... a breve lo migliorerò rendendolo un pò più usabile :DYari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com2tag:blogger.com,1999:blog-1511468527759599388.post-79986142385035396582009-11-02T12:46:00.000-08:002011-10-05T00:43:14.052-07:003D.5b) XNA Tutorial 3d: HLSL shader in XNA - Diffuse lightCiao a tutti!<br />Nello scorso Post vi ho raccontato i concetti base per capire come funzionano gli shader in XNA e abbiamo prodotto uno shader Ambient lighting.<br />Oggi vedremo invece come far interagire in maniera leggermente più complessa una semplice fonte di luce con una mesh attraverso il diffuse lighting.<br /><br /><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/ovZ7P21nTlc&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/ovZ7P21nTlc&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object><br /><br /><span style="font-weight: bold;">Diffuse Lighting</span><br />Questo tipo di illuminazione è generato da una fonte di luce che ha unicamente informazione di direzione e intensità, quindi non è associabile a una posizione specifica nello spazio. Potrebbe essere rappresentata da infiniti raggi paralleli. La logica tramite la quale questa luce interagisce con la mesh è la seguente:<br />Più è piccolo l'angolo di incidenza tra la normale della superficie e il vettore della luce, maggiore sarà il riflesso della luce sulla superficie. Quindi una luce diretta perfettamente verso la normale di una superficie verrà riflessa al massimo, una perpedicolare non verrà riflessa.<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVilJVGMkJONLFbnriMM7qTmT1VkFC_-5jIZjS6yn0BUG1Yg9A_RuZzn4SwyzOhTTzXxLfA1kg-EG2buXDLUVXaOpXniejYr89VqEKATd3uQwEAOwJkcom54X3wLc6TtYSK7zCB5CPYTs/s1600-h/diffuse.jpg"><img style="cursor: pointer; width: 400px; height: 133px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgVilJVGMkJONLFbnriMM7qTmT1VkFC_-5jIZjS6yn0BUG1Yg9A_RuZzn4SwyzOhTTzXxLfA1kg-EG2buXDLUVXaOpXniejYr89VqEKATd3uQwEAOwJkcom54X3wLc6TtYSK7zCB5CPYTs/s400/diffuse.jpg" alt="" id="BLOGGER_PHOTO_ID_5399628182252113746" border="0" /></a><br /><br />Per cercare di spiegarvi meglio il concetto ho creato queste 3 semplici immagini, nella prima potete notare che l'angolo che si crea tra la normale e la luce è molto ampio, in questo caso la luce verrà riflessa molto poco, mentre nell'ultimo caso sarà quasi totalmente riflessa.<br /><br />Passiamo direttamente al codice:<br /><br /><span style="font-weight: bold;">diffuse.fx</span>------------------------------------------------------------<br /><pre>float4x4 World<span class="operator">;</span><br />float4x4 View<span class="operator">;</span><br />float4x4 Projection<span class="operator">;</span><br /><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">//1 Nuove variabili--------------------------------------------</span><br />float4x4 WorldInverseTranspose<span class="operator">;</span><br /><br />float3 DiffuseLightDirection<span class="operator"> =</span> float3<span class="operator">(</span><span class="int">1</span><span class="operator">,</span><span class="float"> 0.5</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span><br />float4 DiffuseColor<span class="operator"> =</span> float4<span class="operator">(</span><span class="float">0.4</span><span class="operator">,</span><span class="float"> 0.5</span><span class="operator">,</span><span class="float"> 0.9</span><span class="operator">,</span><span class="int"> 1</span><span class="operator">);</span><span class="type"><br />float</span> DiffuseIntensity<span class="operator"> =</span><span class="float"> 0.09</span><span class="operator">;</span><br /><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">//2 Variabili relative all'ambient light------------------------</span><br />float4 AmbientColor<span class="operator"> =</span> float4<span class="operator">(</span><span class="float">0.3</span><span class="operator">,</span><span class="float">0.3</span><span class="operator">,</span><span class="float">0.3</span><span class="operator">,</span><span class="float">0.3</span><span class="operator">);</span><span class="type"><br />float</span> AmbientIntensity<span class="operator"> =</span><span class="float"> 0.1</span><span class="operator">;</span><span class="comment"><br /></span><span class="keyword"><br /><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">//3-------------------------------------------------------------</span><br /><span style="font-weight: bold;">struct</span></span><span style="font-weight: bold;"> VertexShaderInput</span><span class="operator"><br />{</span><br />float4 Position<span class="operator"> :</span> POSITION0<span class="operator">;</span><br />float4 Normal<span class="operator"> :</span> NORMAL0<span class="operator">;<br />};</span><span class="keyword"><br /><br /><br /><span style="font-weight: bold;">struct</span></span><span style="font-weight: bold;"> VertexShaderOutput</span><span class="operator"><br />{</span><br />float4 Position<span class="operator"> :</span> POSITION0<span class="operator">;</span><br />float4 Color<span class="operator"> :</span> COLOR0<span class="operator">;<br />};</span><br /><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">//4---------------------------------------------------------------</span><br /><span style="font-weight: bold;">VertexShaderOutput VertexShaderFunction</span><span style="font-weight: bold;" class="operator">(</span><span style="font-weight: bold;">VertexShaderInput input</span><span class="operator"><span style="font-weight: bold;">)</span><br />{</span><br />VertexShaderOutput output<span class="operator">;</span><br />float4 worldPosition<span class="operator"> =</span> mul<span class="operator">(</span>input<span class="operator">.</span>Position<span class="operator">,</span> World<span class="operator">);</span><br />float4 viewPosition<span class="operator"> =</span> mul<span class="operator">(</span>worldPosition<span class="operator">,</span> View<span class="operator">);</span><br />output<span class="operator">.</span>Position<span class="operator"> =</span> mul<span class="operator">(</span>viewPosition<span class="operator">,</span> Projection<span class="operator">);</span><br /><br />float4 normal<span class="operator"> =</span> mul<span class="operator">(</span>input<span class="operator">.</span>Normal<span class="operator">,</span> WorldInverseTranspose<span class="operator">);</span><span class="type"><br />float</span> lightIntensity<span class="operator"> =</span> dot<span class="operator">(</span>normal<span class="operator">,</span> DiffuseLightDirection<span class="operator">);</span><br />output<span class="operator">.</span>Color<span class="operator"> =</span> DiffuseColor<span class="operator"> *</span> DiffuseIntensity<span class="operator"> *</span> lightIntensity<span class="operator">;</span><span class="flow"><br /><br />return</span> output<span class="operator">;<br />}</span><br /><br /><br /><span style="font-weight: bold; color: rgb(255, 0, 0);">//5--------------------------------------------------------------</span><br /><span style="font-weight: bold;">float4 PixelShaderFunction</span><span style="font-weight: bold;" class="operator">(</span><span style="font-weight: bold;">VertexShaderOutput input</span><span style="font-weight: bold;" class="operator">) :</span><span style="font-weight: bold;"> COLOR0</span><span class="operator"><br />{</span><span class="flow"><br />return</span> input<span class="operator">.</span>Color<span class="operator"> +</span> AmbientColor<span class="operator"> *</span> AmbientIntensity<span class="operator">;<br />}</span><br /><br /><br /><br /><span style="font-weight: bold;">technique Technique1</span><span class="operator"><br />{</span><br />pass Pass1<span class="operator"><br />{</span><br /><br /> VertexShader<span class="operator"> =</span> compile vs_1_1 VertexShaderFunction<span class="operator">();</span><br /> PixelShader<span class="operator"> =</span> compile ps_1_1 PixelShaderFunction<span class="operator">();<br />}<br />}</span><br /></pre><br />Come per lo scorso tutorial ho diviso il codice in 4 blocchi, analizziamolo velocemente<br /><br /><span style="font-weight: bold;">1 Nuove variabili</span><span style="font-family:monospace;"><br /></span><pre>WorldInverseTranspose<span class="operator">;</span></pre>Prima abbiamo parlato di "normale della superficie", in realtà quello che interessa non è solo la normale delle superficie, ma la normale posizionata nello spazio della nostra scena. La variabile WorldInverseTranspose servirà per definire questa informazione.<br /><br /><pre>float3 DiffuseLightDirection<span class="operator"> =</span> float3<span class="operator">(</span><span class="int">1</span><span class="operator">,</span><span class="float"> 0.5</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span><br />float4 DiffuseColor<span class="operator"> =</span> float4<span class="operator">(</span><span class="float">0.4</span><span class="operator">,</span><span class="float"> 0.5</span><span class="operator">,</span><span class="float"> 0.9</span><span class="operator">,</span><span class="int"> 1</span><span class="operator">);</span><span class="type"><br />float</span> DiffuseIntensity<span class="operator"> =</span><span class="float"> 0.09</span><span class="operator">;</span></pre>Sono le variabili che identificano la luce definendone la direzione, il colore e l'intensita.<br /><br /><span style="font-weight: bold;">2 variabili ambientLight</span><span style="font-family:monospace;"><br /></span>Sono le variabili che abbiamo visto nella lezione scorsa utili per definire la luce ambientale. Mi sono dimenticato di dirvi che utilizzeremo anche questa luce... quindi andremo a sommare due tipi di materiali per produrre un effetto più completo.<br /><br /><span style="font-weight: bold;">3 definizioni della struttura vertex shader (in e out)<br /></span>In questo tipo di materiale avremo bisogno di avere in ingresso oltre che l'informazione di posizione del vertice anche l'informazione<span style="font-weight: bold;"> </span>della normale,<span style="font-weight: bold;"> </span>che come vi spiegavo prima, verrà messa a confronto con la direzione della luce per il calcolo dell'intensità.<span style="font-weight: bold;"><br /></span>L'output del vertex shader riporterà informazione di posizione e colore<span style="font-weight: bold;">.</span>Infatti a seguito dei calcoli relativi all'angolo di incidenza dei due vettori, andremo a modificare il colore del vertice per garantire l'effetto di "riflessione della luce".<span style="font-weight: bold;"><br /><br />4 Vertex shader<br /></span>All'inizio della funzione andremo a definire la posizione del vertice in base alla nostra world.<br />(posizioneremo il vertice nella scena)<br />nelle righe che riporto qui sotto andremo invece a definire l'effetto della luce sul vertice:<br /><pre> float4 normal<span class="operator"> =</span> mul<span class="operator">(</span>input<span class="operator">.</span>Normal<span class="operator">,</span> WorldInverseTranspose<span class="operator">);</span><span class="type"><br />float</span> lightIntensity<span class="operator"> =</span> dot<span class="operator">(</span>normal<span class="operator">,</span> DiffuseLightDirection<span class="operator">);</span><br />output<span class="operator">.</span>Color<span class="operator"> =</span> DiffuseColor<span class="operator"> *</span> DiffuseIntensity<span class="operator"> *</span> lightIntensity<span class="operator">;</span><span class="flow"><br /></span></pre>normal: moltiplichiamo la normale del vertice per la matrice che identifica la matrice inversa, trasposta della world (in realtà ho notato che basta anche l'inversa....) .Questa moltiplicazione ha lo scopo di definire la normale non solo sul modello... ma sul posizionamento della mesh nella scena, tenendo dunque conto di spostamenti e rotazioni.<br /><br />lightIntensity : effettueremo il prodotto dot tra la normale e la direzione della luce (riguardate l'immagine con le 3 situazioni....) per definire quanto sia l'incidenza tra la normale e la luce.<br /><a href="http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation">http://en.wikipedia.org/wiki/Dot_product#Geometric_interpretation</a> guardare l'immagine su wikipedia.. potrebbe chiarirvi le idee riguardo questa operazione.<br /><br />output.Color : otteniamo il colore del vertice moltiplicando i valori che abbiamo impostato per la luce diffuse e sopratutto aggiungiamo il fattore intensità definito tramite all'interazione tra normale e luce.<br /><br /><span style="font-weight: bold;">5 Pixel Shader</span><br />Non resta che definire il pixel shader utilizzando le informazioni di colore ricevute dal vertex shader e aggiungendo i parametri di luce ambientale definiti in testa al file.<br /><br /><pre><span class="flow">return</span> input<span class="operator">.</span>Color<span class="operator"> +</span> AmbientColor<span class="operator"> *</span> AmbientIntensity<span class="operator">;</span></pre><br />A questo punto dobbiamo fare qualche piccola delucidazione sul file game1.cs ... ma niente di difficile, il grosso lo avete visto sopra.<br /><br />Prima di tutto modifichiamo la funzione Draw per chiamare La DrawModelDiffuse invece che la funzione ambient del tutorial precedente ( se scaricate i sorgenti a fondo pagina troverete già tutto pronto...)<br /><br /><span style="font-weight: bold;">Draw</span><br /><pre><span class="keyword"> protected</span> override<span class="type"> void</span> Draw<span class="operator">(</span>GameTime gameTime<span class="operator">)<br /> {</span><br /> device<span class="operator">.</span>Clear<span class="operator">(</span>ClearOptions<span class="operator">.</span>Target<span class="operator"> |</span> ClearOptions<span class="operator">.</span>DepthBuffer<span class="operator">,</span> Color<span class="operator">.</span>SlateGray<span class="operator">,</span><span class="int"> 1</span><span class="operator">,</span><span class="int"> 0</span><span class="operator">);</span><br /> <br /> <span style="font-weight: bold;">DrawModelDiffuse</span><span class="operator">(</span>myModel<span class="operator">,</span> world<span class="operator">);</span><br /> base<span class="operator">.</span>Draw<span class="operator">(</span>gameTime<span class="operator">);<br /> }</span></pre><br /><span style="font-weight: bold;">DrawModelDiffuse</span><br /><br /><pre><span class="comment"> //Funzione per utilizzare lo shader diffuse<br /></span><span class="keyword"> private</span><span class="type"> void</span> DrawModelDiffuse<span class="operator">(</span>Model model<span class="operator">,</span> Matrix world<span class="operator">)<br /> {</span><br /> foreach<span class="operator"> (</span>ModelMesh mesh in model<span class="operator">.</span>Meshes<span class="operator">)<br /> {</span><br /> foreach<span class="operator"> (</span>ModelMeshPart part in mesh<span class="operator">.</span>MeshParts<span class="operator">)<br /> {</span><br /> part<span class="operator">.</span>Effect<span class="operator"> =</span> effect<span class="operator">;</span><br /><br /> worldInverseTransposeMatrix<span class="operator"> =</span> Matrix<span class="operator">.</span>Transpose<span class="operator">(</span>Matrix<span class="operator">.</span>Invert<span class="operator">(</span>mesh<span class="operator">.</span>ParentBone<span class="operator">.</span>Transform<span class="operator"> *</span> world<span class="operator">));</span><br /> effect<span class="operator">.</span>Parameters<span class="operator">[</span><span class="string">"WorldInverseTranspose"</span><span class="operator">].</span>SetValue<span class="operator">(</span>worldInverseTransposeMatrix<span class="operator">);</span><br /><br /> effect<span class="operator">.</span>Parameters<span class="operator">[</span><span class="string">"World"</span><span class="operator">].</span>SetValue<span class="operator">(</span>world<span class="operator"> *</span> mesh<span class="operator">.</span>ParentBone<span class="operator">.</span>Transform<span class="operator">);</span><br /> effect<span class="operator">.</span>Parameters<span class="operator">[</span><span class="string">"View"</span><span class="operator">].</span>SetValue<span class="operator">(</span>fpsCam<span class="operator">.</span>ViewMatrix<span class="operator">);</span><br /> effect<span class="operator">.</span>Parameters<span class="operator">[</span><span class="string">"Projection"</span><span class="operator">].</span>SetValue<span class="operator">(</span>fpsCam<span class="operator">.</span>ProjectionMatrix<span class="operator">);<br /> }</span><br /> mesh<span class="operator">.</span>Draw<span class="operator">();<br /> }<br /> }</span></pre>Questa funzione setta alcuni dei parametri che avete visto dentro l'effetto.<br /><br />Ricordate nella loadContent di decommentare il caricamente dello shader diffuse<br /> effect = Content.Load<effect>("effect/Diffuse");<br /><br />Nel prossimo post vedremo come gestire lo shader con specular light.<br /><br /><br />IMPORTANTE:<br />Il materiale di questa introduzione agli shader è stato prodotto grazie a questo ottimo blog : <a href="http://rbwhitaker.wikidot.com/diffuse-lighting-shader"><span style="font-weight: bold;">http://rbwhitaker.wikidot.com/diffuse-lighting-shader</span></a><br /><br />Mi sono dimenticato di segnalarlo nel post precedente! quindi colgo l'occasione per farlo ora.<br /><br /><br /><span style="font-weight: bold;">Sorgenti:</span><br /><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.4diffuse.hlsl.zip">imparandoxna_3d.4diffuse.hlsl.zip</a></effect>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com3tag:blogger.com,1999:blog-1511468527759599388.post-45955020040797866632009-10-08T12:06:00.000-07:002011-10-05T00:44:15.937-07:003D.5) XNA Tutorial 3d: HLSL shader in XNA<span style=";font-family:Arial,sans-serif;font-size:100%;" >Ciao a Tutti!</span><p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">Eccomi di nuovo dopo una lunghissima pausa !!!
<br />Mi dispiace aver atteso tanto per creare il nuovo tutorial, ma il tempo libero è stato veramente poco e se devo dire la verità anche la voglia non era molta... :P (w la sincerità) .
<br />Questo periodo di blackout è stato parecchio utile, ne ho approfittato per studiacchiare un pò il discorso shader e HLSL, andiamo al dunque senza girarci troppo intorno e cerchiamo di capire di cosa si tratta:</span></p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br /></span><span style="font-size:100%;"><b>PROCESSO SHADER </b></span> </p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;"><span style="font-weight: normal;">Questa immagine rappresenta il percorso che viene seguito per convertire i dati creati dall'applicazione in informazioni </span></span><span style="font-size:100%;"><span style="font-weight: normal;">visualizzate a Monitor.</span></span></p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNp3qIoEELOCJ1o0MJxe4I5fwIC1sDzXDnVepv6sEfUIKyddhm0SgKXwFPz5TGjcvHjLhYPEylf-XPByiDM12A5XHLD-ZV4CWai6pTOLg-ONXBb4xLbH4hv-Tj5svmHKF8-ywy-_Pt85U/s1600-h/lezionehlsl_html_7e85f003.jpg"><img style="cursor: pointer; width: 460px; height: 460px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjNp3qIoEELOCJ1o0MJxe4I5fwIC1sDzXDnVepv6sEfUIKyddhm0SgKXwFPz5TGjcvHjLhYPEylf-XPByiDM12A5XHLD-ZV4CWai6pTOLg-ONXBb4xLbH4hv-Tj5svmHKF8-ywy-_Pt85U/s400/lezionehlsl_html_7e85f003.jpg" alt="" id="BLOGGER_PHOTO_ID_5391477802524561922" border="0" /></a></span><span style="font-size:100%;">
<br /></span></p><p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">Noterete che le funzionalità di Vertex e Pixel shader sono svolte come pipeline nella GPU.
<br /></span></p><p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br /><b>VERTEX SHADER</b>
<br />Attraverso i vertex shader vengono visitati tutti i vertici nella scena, effettuando su questi eventuali operazioni che possono andare dalla modifica delle informazioni di posizione fino alla definizione del colore del vertice. </span> </p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">Vi ricordo che definire il colore di un vertice in XNA fa si che si crei un'interpolazione tra i colori dei vari vertici... lo abbiamo visto in <a href="http://imparandoxna.blogspot.com/2009/04/3d2-xna-tutorial-3d-disegnare-primitive.html">questo tutorial</a> riporto qui il risultato: </span> </p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO-aft1Ff5VfB8iF6ym7BdV_YWlFP76E4B-AaWLv-DBRzGwXnnDsfjBOtw2zl6GFWnTAgDt_iPD5GoIk_apW6dl6-yWKB3uD0M2yigGIQtcxE5GKTosCs7EEgbi3w6oJ-xdlQGeXsBMQg/s1600-h/lezionehlsl_html_7fa787bb.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 235px; height: 183px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgO-aft1Ff5VfB8iF6ym7BdV_YWlFP76E4B-AaWLv-DBRzGwXnnDsfjBOtw2zl6GFWnTAgDt_iPD5GoIk_apW6dl6-yWKB3uD0M2yigGIQtcxE5GKTosCs7EEgbi3w6oJ-xdlQGeXsBMQg/s400/lezionehlsl_html_7fa787bb.jpg" alt="" id="BLOGGER_PHOTO_ID_5391478059757778642" border="0" /></a></span><span style="font-size:100%;">Una volta che sono state svolte le operazione nel vertex shader, viene lancianto il processo Rasterizzazione.</span></p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br />Lo scopo di questo processo è convertire i triangoli che definiscono la scena ( o l'oggetto) in Pixel da renderizzare a monitor.</span></p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br />Nel caso di XNA, uno dei compiti principali del Vertex Shader (non ricordo assolutamente se questo valga anche per DirectX) è quello di posizionare il modello ricevendo i dati View, World e Projection Matrix.</span></p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br /></span></p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">
<br /><b>PiXEL SHADER</b>
<br />Ora che la scena è stata convertita in Pixel è il turno del Pixel Shader, che effettuerà operazioni su tutti i pixel visibili. </span> </p> <p style="margin-bottom: 0cm;font-family:arial;"><span style="font-size:100%;">Al termine di questa operazione l'immagine è pronta per essere presentata a Video. La differenza principale tra i due passaggi è dunque data dal punto nel quale opereremo, Vertici e Pixel!
<br />
<br /><b>HLSL</b>
<br />Poco fa parlavo di "operazioni" eseguite dai vertex/pixel shader su ogni vertice/pixel disegnato. Tutto quello che viene eseguito durante questi passaggi è definito attraverso linguaggio HLSL (High Level Shader Language). Il modo migliore per raccontarvi qualcosa su questo linguaggio e su come scrivere i vostri shader penso che sia la pratica diretta sul codice.... quindi ecco qui quello che faremo:
<br />
<br />1) Creeremo una scena 3d con una delle solite bellissime astronavi di Battlestar Galactica :)
<br />2) Creeremo un Ambient light Shader, che darà alla scena un colore omogeneo e piatto, basato su una luce ambientale non direzionale, regolabile per colore e intensità.....in poche parole una mer*a :P dato che come vedrete non si distingueranno le facce dell'oggetto.... ma per ora serve per imparare quindi ben venga!!
<br />
<br />
<br />Prima di tutto vi presento il file ambient.fx che è il punto nel quale definiremo il nostro shader:</span></p> <p style="margin-bottom: 0.5cm;font-family:arial;" align="left"><span style="font-size:100%;">
<br /><b>ambient.fx</b>
<br /></span></p> <pre style="font-style: normal; text-align: left;"><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><b>// 1 Variabili settate tramite l'applicazione-----------------------------------</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">extern</span> float4x4 World<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">extern</span> float4x4 View<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">extern</span> float4x4 Projection<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><i>//Impostazioni (provare a giocare con questi parametri)---------------------</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >float4 AmbientColor<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> float4<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 153, 0);">1</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);">1</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);">1</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);">1</span><span style="color: rgb(102, 51, 0);"><b>);</b></span><span style="color: rgb(153, 153, 153);"> </span><span style="color: rgb(153, 153, 153);"><i>//Colore passato tramite l'ambiente</i></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 102, 51);">float</span> AmbientIntesity<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 102, 0);"> 0.2</span><span style="color: rgb(102, 51, 0);"><b>;</b></span><span style="color: rgb(153, 153, 153);"> </span><span style="color: rgb(153, 153, 153);"><i>//intesità</i></span></span><span style="font-size:100%;">
<br />
<br />
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><b>// 2 VERTEX SHADER--------------------------------------------------------------</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><i>//Struttura per definire l'input per il vertex shader</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">struct</span> VertexShaderInput</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > float4 Position<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>:</b></span> <b>POSITION0</b><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>};</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><i>//Struttura per definire l'output del vertex shader</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">struct</span> VertexShaderOutput</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > float4 Position<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>:</b></span> <b>POSITION0</b><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>};</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><i>//La nostra funzione vertex shader</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >VertexShaderOutput VertexShaderFunction<span style="color: rgb(102, 51, 0);"><b>(</b></span>VertexShaderInput input<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > VertexShaderOutput output<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > float4 worldPosition<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> mul<span style="color: rgb(102, 51, 0);"><b>(</b></span>input<span style="color: rgb(102, 51, 0);"><b>.</b></span>Position<span style="color: rgb(102, 51, 0);"><b>,</b></span> World<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > float4 viewPosition<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> mul<span style="color: rgb(102, 51, 0);"><b>(</b></span>worldPosition<span style="color: rgb(102, 51, 0);"><b>,</b></span> View<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > output<span style="color: rgb(102, 51, 0);"><b>.</b></span>Position<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> mul<span style="color: rgb(102, 51, 0);"><b>(</b></span>viewPosition<span style="color: rgb(102, 51, 0);"><b>,</b></span> Projection<span style="color: rgb(102, 51, 0);"><b>) ;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 0, 0);"> return</span> output<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><i><b>// 3 PIXEL SHADER----------------------------------------------------------------</b></i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >float4 PixelShaderFunction<span style="color: rgb(102, 51, 0);"><b>(</b></span>VertexShaderOutput input<span style="color: rgb(102, 51, 0);"><b>) :</b></span> <b>COLOR0</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 0, 0);"> return</span><span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>AmbientColor<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> AmbientIntesity<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" ><i><b>// 4 TECNICA---------------------------------------------------------------------</b></i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >technique Technique1</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > pass Pass1</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b> {</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > VertexShader<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> compile <b>vs_1_1</b> VertexShaderFunction<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > PixelShader<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> compile <b>ps_1_1</b> PixelShaderFunction<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b> }</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br /></span>
<br /></pre>
<br /><span style=";font-family:Arial,sans-serif;font-size:100%;" >Prima di farvi vedere il codice della scena 3d (che non è lo scopo centrale di questo tutorial...</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >ma che comunque spiegherò passo passo giusto per non farvi incazzare come vipere :P)</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >analiziamo questo codice.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Come noterete l'ho diviso in 4 Macro Blocchi</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >1) variabili passate dall'applicazione</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >2) vertex shader</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >3) pixel shader</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >4) tecnica</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Uno alla volta</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>1)Variabili settate dall'applicazione</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Queste variabili sono definite a livello di applicazione, il che significa che tramite un</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >costrutto particolare, scriveremo direttamente nel nostro game1.cs del codice che invierà queste</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >informazioni allo shader fx ( vedremo dopo come... per ora sappiate solo che sono dati definiti in game1.cs).</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La sintassi della definizione della variabili è simile a C, ma noterete che i tipi di dato sono</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >leggermente diversi. A dire il vero devo studiarli ancora per bene...(<a href="http://msdn.microsoft.com/en-us/library/ee418289%28VS.85%29.aspx">qui la reference</a>) comunque quel float4x4 com'è facile immaginare fa riferimento
<br />a una matrica 4x4 composta di float.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Per ora osservate soltanto il fatto che si tratta delle 3 matrici view, projection e world...</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >e se fate un passo indietro di un tutorial... noterete che sono proprio i valori che passavamo al basic effect.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ecco qui un ripassino :</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>BasicEffect be in mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>Effects<span style="color: rgb(102, 51, 0);"><b>) {</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > be<span style="color: rgb(102, 51, 0);"><b>.</b></span>EnableDefaultLighting<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > be<span style="color: rgb(102, 51, 0);"><b>.</b></span>Projection<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> camera<span style="color: rgb(102, 51, 0);"><b>.</b></span>projection<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > be<span style="color: rgb(102, 51, 0);"><b>.</b></span>View<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> camera<span style="color: rgb(102, 51, 0);"><b>.</b></span>view<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > be<span style="color: rgb(102, 51, 0);"><b>.</b></span>World<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> GetWorld<span style="color: rgb(102, 51, 0);"><b>() *</b></span> mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>2) vertex shader</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Qui abbiamo 3 blocchi:</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >2 strutture e 1 funzione.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Diamo un'occhiata all'immagine del processo shader, notiamo che la funzione vertex shader ha 1 freccia entrante e una uscente...
<br />quindi un input e un output. </span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Le due strutture identificano proprio le 2 frecce.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Sia shader input che shader output hanno lo stesso contenuto, in questo caso:</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>float4</b> Position<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>:</b></span> <b>POSiTiON0</b><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>-float4</b></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > identifica un vettore di 4 float x,y,z,w ( se non sapete cosa sia w, date un'occhiata a <a href="http://andrewharvey4.wordpress.com/2008/09/29/xyzw-in-opengldirect3d-homogeneous-coordinates/">questo link</a>)</span><span style="font-size:100%;">
<br /></span><span style=";font-family:arial;font-size:100%;" >-Mentre per <b>:POSiTiON0</b> dobbiamo fare un paio di riflessioni in più:</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Abbiamo detto che lo scopo del vertex shader è quello di elaborare ogni vertice, e abbiamo anche detto</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >che possiamo modificare informazioni di posizione e colore per ogni vertice elaborato....la voce (chiamata SEMANTICA) :POSITION0 identifica
<br />che quella variabile è
<br />associata all'informazioni POSIZIONE del vertice.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Una lista completa delle semantiche la trovate a <a href="http://msdn.microsoft.com/en-us/library/ee418355%28VS.85%29.aspx">questo link.</a></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Quindi facciamo un passo indietro, nel vertex shader entrano dei dati, definiti dalla struttura VertexShaderInput.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La struttura è composta da una variabile float4 con semantica :POSITION0, questo vuol dire che i dati che entranno</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >nella vertex shader sono i dati di posizione del vertice.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Mettiamo caso che stiamo disegnando triangolo; la funzione VertexShader ricevere a ciclo le posizioni dei 3 vertici che lo compongono.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Quindi diciamo che POSITION0 è una funzionalità predefinità dal linguaggio HLSL che serve proprio per collegare la logica definita nell'applicazione con lo shader.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La struttura VertexShaderOutput (quella che identifica la freccia uscente dalla funzione VertexShader) è composta come dicevamo prima nello stesso identico modo,
<br />ma in questo caso identifica un output....quindi facciamo due più due e otteniamo che in questo caso siamo di fronte a una funzione VerteXShader che riceve in ingresso la posizione di un vertice</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >la elabora (attraverso world -view - projection) e quindi restituisce la nuova posizione del vertice.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ricordate che si possono modificare anche altri paramentri del vertice....(in questo esempio lavoriamo solo sulla posizione).</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ora guardiamo in che modo la funzione VertexShader elabora la posizione del vertice in ingresso:</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 0, 0);"><b>VertexShaderOutput</b></span> <b>VertexShaderFunction</b><span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(51, 204, 0);"><b>VertexShaderInput</b></span> input<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > VertexShaderOutput output<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > float4 worldPosition<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> <b>mul</b><span style="color: rgb(102, 51, 0);"><b>(</b></span>input<span style="color: rgb(102, 51, 0);"><b>.</b></span>Position<span style="color: rgb(102, 51, 0);"><b>,</b></span> World<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > float4 viewPosition<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> <b>mul</b><span style="color: rgb(102, 51, 0);"><b>(</b></span>worldPosition<span style="color: rgb(102, 51, 0);"><b>,</b></span> View<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > output<span style="color: rgb(102, 51, 0);"><b>.</b></span>Position<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> <b>mul</b><span style="color: rgb(102, 51, 0);"><b>(</b></span>viewPosition<span style="color: rgb(102, 51, 0);"><b>,</b></span> Projection<span style="color: rgb(102, 51, 0);"><b>) ;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 0, 0);"> return</span> output<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ok leggete il prototipo e capiamo subito che .... l'output è un <span style="color: rgb(255, 0, 0);">VertexShaderOutput,</span> la funzione si chiama</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>VertexShaderFunction</b> e riceve in ingresso un <span style="color: rgb(51, 204, 0);">VertexShaderInput</span>.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La funzione non fa altro che far passare la posizione del vertice attraverso una moltiplicazione con le 3 matrici principali, ricevute dall'applicazione (vi ricordate? il blocco 1 visto qualche riga fa... )</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Mentre la funzione mul è un costrutto predefinito di hlsl che si occupa di moltiplicare 2 matrici. </span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>3) pixel shader</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >float4 <b>PixelShaderFunction</b><span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(255, 0, 0);"><b>VertexShaderOutput</b></span> input<span style="color: rgb(102, 51, 0);"><b>) :</b></span> <b>COLOR0</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 0, 0);"> return</span><span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>AmbientColor<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> AmbientIntesity<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La scopo di questa funzione è di dare a ogni pixel disegnato, un colore basato sulla luce ambientale.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Quindi tramite la moltiplicazione AmbientColor * AmbientIntensity ogni pixel assumerà lo stesso color, la cosa interessante da notare è questo colore
<br />non è definito sull'oggetto tramite materiali, ma è definito attraverso il nostro effetto!</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La sintassi della funzione e leggermente diversa dalla Vertex Shader ma solo a scopo dimostrativo... infatti le due sintassi sono interscambiabili.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ma vediamo dove sta la differenza. Noterete che in questo caso la Semantica :COLOR0 è posizionata in linea al nome funzione prima della definizione.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Questo sta ad indicare che l'OUTPUT della funzione sarà il COLORE del pixel elaborato.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Logica quindi del tutto identica al vertex shader, notate che in questo caso l'output del vertexShader viene diretto come input del PixelShader.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>4)Tecnica</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Anche se è l'ultima parte che tratteremo in realtà questa è la sezione del codice che viene letta per prima.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >technique Technique1</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > pass Pass1</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b> {</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > VertexShader<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> compile <b>vs_1_1</b> VertexShaderFunction<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > PixelShader<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> compile <b>ps_1_1</b> PixelShaderFunction<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b> }</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Andiamo ad analizzare il codice partendo dall'interno.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Una tecnica richiede che per ogni passo vengano settati i paramentri VertexShader e PixelShader che, come è facile immaginare, identificano le funzioni che
<br />associamo a questi due processi.</span> <span style=";font-family:Arial,sans-serif;font-size:100%;" >Nel nostro caso andremo ad associare le funzioni create precedentemente.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La sintassi è un pò particolare :</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >compile vs_1_1 indica che la funzione<b> VertexShaderFunction()</b> viene compilata utilizzando la <b>versione 1</b> di vertex shader.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Alcune funzionalità potrebbero essere supportate solo da versione successive (2,3) di vertex shader.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >E' buona pratica utilizzare sempre la versione più bassa disponibile in grado di supportare le nostre necessità, questo farà si che anche chi utilizza
<br />schede video "datate" possa visualizzare i nostri shader.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Una tecnica può essere composta da più passi che verranno eseguiti in successione, in ogni passo potrete definire le vostre funzioni, i risultati delle quali si sommerrano
<br />per otterenere un effetto finale composto appunto da più passi.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >All'interno di uno shader possono essere create diverse tecniche e tramite l'applicazione si potrebbe decidere di utilizzare una tecnica piuttosto che un'altra.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Questa scelta potrebbe essere guidata dal tipo di scheda video dell'utente che utilizzerà la nostra applicazione, potremmo infatti decidere che in base al tipo di dettaglio grafico scelto venga
<br />caricata una tecnica più leggera o pià pesante.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ora che abbiamo analizzato lo shader in tutti suoi dettagli vediamo il codice dell'applicazione.</span><span style="font-size:100%;">
<br />
<br /></span><span style="color: rgb(255, 0, 0);font-family:arial;font-size:100%;" ><b>Come sopra.... non fate copia e incolla! usate i sorgenti a fondo articolo :D</b></span>
<br /><pre><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">using</span> System<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">using</span> System<span style="color: rgb(102, 51, 0);"><b>.</b></span>Collections<span style="color: rgb(102, 51, 0);"><b>.</b></span>Generic<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">using</span> System<span style="color: rgb(102, 51, 0);"><b>.</b></span>Linq<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" >......................etcetcetc</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">namespace</span> hlsl_start</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>{</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">public class</span> Game1<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>:</b></span> Microsoft<span style="color: rgb(102, 51, 0);"><b>.</b></span>Xna<span style="color: rgb(102, 51, 0);"><b>.</b></span>Framework<span style="color: rgb(102, 51, 0);"><b>.</b></span>Game</span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > GraphicsDeviceManager graphics<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > GraphicsDevice device<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /><i>//L'effetto Basic (standard di xna)</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >BasicEffect basicEffect<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /><i>//Il nostro effetto</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Effect effect<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>
<br />//Ottima camera da libro xna 3.0 recipes</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > QuakeCamera fpsCam<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /><i>//Il modello 3d</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Model myModel<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <span style="font-style: italic;">
<br /></span><i>//Matrici</i></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Matrix world<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>Identity<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Matrix projection<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Matrix worldInverseTransposeMatrix<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Matrix<span style="color: rgb(102, 51, 0);"><b>[]</b></span> modelTransforms<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /><i>//Varie</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(255, 102, 51);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 102, 51);">float</span> angle<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 102, 0);"> 0.0f</span><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Vector3 viewVector<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">private</span> Vector3 Position<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Vector3<span style="color: rgb(102, 51, 0);"><b>.</b></span>One<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(255, 102, 51);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 102, 51);">float</span> aspectRatio<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">public</span> Game1<span style="color: rgb(102, 51, 0);"><b>()</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > graphics<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 0, 0);"> new</span> GraphicsDeviceManager<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 0, 0);">this</span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Content<span style="color: rgb(102, 51, 0);"><b>.</b></span>RootDirectory<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(0, 153, 0);"> "Content"</span><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<span style="color: rgb(102, 51, 0);"><b>()</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//istanzia la camera</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > fpsCam<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 0, 0);"> new</span> QuakeCamera<span style="color: rgb(102, 51, 0);"><b>(</b></span>GraphicsDevice<span style="color: rgb(102, 51, 0);"><b>.</b></span>Viewport<span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 0, 0);"> new</span> Vector3<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 153, 0);">10</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 10</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 50</span><span style="color: rgb(102, 51, 0);"><b>),</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /> <i>//setta ratio e pojection</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > aspectRatio<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> graphics<span style="color: rgb(102, 51, 0);"><b>.</b></span>GraphicsDevice<span style="color: rgb(102, 51, 0);"><b>.</b></span>Viewport<span style="color: rgb(102, 51, 0);"><b>.</b></span>Width<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>/</b></span> graphics<span style="color: rgb(102, 51, 0);"><b>.</b></span>GraphicsDevice<span style="color: rgb(102, 51, 0);"><b>.</b></span>Viewport<span style="color: rgb(102, 51, 0);"><b>.</b></span>Height<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > projection<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>CreatePerspectiveFieldOfView<span style="color: rgb(102, 51, 0);"><b>(</b></span>MathHelper<span style="color: rgb(102, 51, 0);"><b>.</b></span>ToRadians<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 102, 0);">45.0f</span><span style="color: rgb(102, 51, 0);"><b>),</b></span> aspectRatio<span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 102, 0);"> 1.0f</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 102, 0);"> 10000.0f</span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > base<span style="color: rgb(102, 51, 0);"><b>.</b></span>Initialize<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<span style="color: rgb(102, 51, 0);"><b>()</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >device<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> graphics<span style="color: rgb(102, 51, 0);"><b>.</b></span>GraphicsDevice<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//Imposta il modello 3d</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b> myModel</b><span style="color: rgb(102, 51, 0);"><b> =</b></span> <b>Content</b><span style="color: rgb(102, 51, 0);"><b>.</b></span><b>Load</b><span style="color: rgb(102, 51, 0);"><b><</b></span><b>Model</b><span style="color: rgb(102, 51, 0);"><b>>(</b></span><span style="color: rgb(0, 153, 0);"><b>"model/cylon"</b></span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > modelTransforms<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 0, 0);"> new</span> Matrix<span style="color: rgb(102, 51, 0);"><b>[</b></span>myModel<span style="color: rgb(102, 51, 0);"><b>.</b></span>Bones<span style="color: rgb(102, 51, 0);"><b>.</b></span>Count<span style="color: rgb(102, 51, 0);"><b>];</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >myModel<span style="color: rgb(102, 51, 0);"><b>.</b></span>CopyAbsoluteBoneTransformsTo<span style="color: rgb(102, 51, 0);"><b>(</b></span>modelTransforms<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//Imposta gli effetti (ne utilizzaremo uno per volta... quindi commentate e decommentate a seconda del caso</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//basicEffect = new BasicEffect(device, null);</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//effect = Content.Load("effect/Specular");</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//effect = Content.Load("effect/Specular");</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b> effect</b><span style="color: rgb(102, 51, 0);"><b> =</b></span> <b>Content</b><span style="color: rgb(102, 51, 0);"><b>.</b></span><b>Load</b><span style="color: rgb(102, 51, 0);"><b><</b></span><b>Effect</b><span style="color: rgb(102, 51, 0);"><b>>(</b></span><span style="color: rgb(0, 153, 0);"><b>"effect/Ambient"</b></span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<span style="color: rgb(102, 51, 0);"><b>(</b></span>GameTime gameTime<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//Opzioni per la camera</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >GamePadState gamePadState<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> GamePad<span style="color: rgb(102, 51, 0);"><b>.</b></span>GetState<span style="color: rgb(102, 51, 0);"><b>(</b></span>PlayerIndex<span style="color: rgb(102, 51, 0);"><b>.</b></span>One<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > MouseState mouseState<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Mouse<span style="color: rgb(102, 51, 0);"><b>.</b></span>GetState<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >KeyboardState keyState<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Keyboard<span style="color: rgb(102, 51, 0);"><b>.</b></span>GetState<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>Update<span style="color: rgb(102, 51, 0);"><b>(</b></span>mouseState<span style="color: rgb(102, 51, 0);"><b>,</b></span> keyState<span style="color: rgb(102, 51, 0);"><b>,</b></span> gamePadState<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /> </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 153, 153);"><i>//per shader specular</i></span> <b>ora non ci interessa...</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > Vector3 cameraLocation<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 153, 0);"> 2</span><span style="color: rgb(102, 51, 0);"><b>*</b></span><span style="color: rgb(153, 0, 0);"> new</span> Vector3<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 153, 0);">0</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 3</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Vector3 cameraTarget<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 0, 0);"> new</span> Vector3<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 153, 0);">0</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /> <i>//Rotazione del modello</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > angle<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>+=</b></span><span style="color: rgb(153, 102, 0);"> 0.01f</span><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(255, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(255, 0, 0);">if</span><span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>angle<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>></b></span><span style="color: rgb(153, 153, 0);"> 359</span><span style="color: rgb(102, 51, 0);"><b>) {</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > angle<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >world<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>CreateRotationY<span style="color: rgb(102, 51, 0);"><b>(</b></span>angle<span style="color: rgb(102, 51, 0);"><b>) *</b></span> Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>CreateScale<span style="color: rgb(102, 51, 0);"><b>(</b></span><span style="color: rgb(153, 102, 0);">0.05f</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 102, 0);"> 0.05f</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 102, 0);"> 0.05f</span><span style="color: rgb(102, 51, 0);"><b>) ;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" >
<br /> <i>//Da usare per lo shader specular</i></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >viewVector<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Vector3<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"><b>(</b></span>cameraTarget<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>-</b></span> cameraLocation<span style="color: rgb(102, 51, 0);"><b>,</b></span> fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ViewMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >viewVector<span style="color: rgb(102, 51, 0);"><b>.</b></span>Normalize<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > base<span style="color: rgb(102, 51, 0);"><b>.</b></span>Update<span style="color: rgb(102, 51, 0);"><b>(</b></span>gameTime<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<span style="color: rgb(102, 51, 0);"><b>(</b></span>GameTime gameTime<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > device<span style="color: rgb(102, 51, 0);"><b>.</b></span>Clear<span style="color: rgb(102, 51, 0);"><b>(</b></span>ClearOptions<span style="color: rgb(102, 51, 0);"><b>.</b></span>Target<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>|</b></span> ClearOptions<span style="color: rgb(102, 51, 0);"><b>.</b></span>DepthBuffer<span style="color: rgb(102, 51, 0);"><b>,</b></span> Color<span style="color: rgb(102, 51, 0);"><b>.</b></span>SlateGray<span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 1</span><span style="color: rgb(102, 51, 0);"><b>,</b></span><span style="color: rgb(153, 153, 0);"> 0</span><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b> DrawModelAmbient</b><span style="color: rgb(102, 51, 0);"><b>(</b></span><b>myModel</b><span style="color: rgb(102, 51, 0);"><b>,</b></span> <b>world</b><span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > base<span style="color: rgb(102, 51, 0);"><b>.</b></span>Draw<span style="color: rgb(102, 51, 0);"><b>(</b></span>gameTime<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//Disegna il modello con lo shader standard</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">public</span><span style="color: rgb(255, 102, 51);"> void</span> DrawModel<span style="color: rgb(102, 51, 0);"><b>(</b></span>Model model<span style="color: rgb(102, 51, 0);"><b>,</b></span> Matrix w<span style="color: rgb(102, 51, 0);"><b>){</b></span> </span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMesh mesh in model<span style="color: rgb(102, 51, 0);"><b>.</b></span>Meshes<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>BasicEffect effect in mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>Effects<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>EnableDefaultLighting<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>World<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> modelTransforms<span style="color: rgb(102, 51, 0);"><b>[</b></span>mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Index<span style="color: rgb(102, 51, 0);"><b>] *</b></span> w<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>View<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ViewMatrix<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Projection<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ProjectionMatrix<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>Draw<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//funzione per utilizzare lo shader Ambient</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">private</span><span style="color: rgb(255, 102, 51);"> void</span> DrawModelAmbient<span style="color: rgb(102, 51, 0);"><b>(</b></span>Model model<span style="color: rgb(102, 51, 0);"><b>,</b></span> Matrix world<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMesh mesh in model<span style="color: rgb(102, 51, 0);"><b>.</b></span>Meshes<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMeshPart part in mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>MeshParts<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > part<span style="color: rgb(102, 51, 0);"><b>.</b></span>Effect<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> effect<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"World"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>world<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"View"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ViewMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"Projection"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ProjectionMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>Draw<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//Funzione per utilizzare lo shader diffuse</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">private</span><span style="color: rgb(255, 102, 51);"> void</span> DrawModelDiffuse<span style="color: rgb(102, 51, 0);"><b>(</b></span>Model model<span style="color: rgb(102, 51, 0);"><b>,</b></span> Matrix world<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMesh mesh in model<span style="color: rgb(102, 51, 0);"><b>.</b></span>Meshes<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMeshPart part in mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>MeshParts<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >part<span style="color: rgb(102, 51, 0);"><b>.</b></span>Effect<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> effect<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >worldInverseTransposeMatrix<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transpose<span style="color: rgb(102, 51, 0);"><b>(</b></span>Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>Invert<span style="color: rgb(102, 51, 0);"><b>(</b></span>mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> world<span style="color: rgb(102, 51, 0);"><b>));</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"WorldInverseTranspose"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>worldInverseTransposeMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"World"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>world<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"View"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ViewMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"Projection"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ProjectionMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>Draw<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style="color: rgb(153, 153, 153);font-family:arial;font-size:100%;" > <i>//Funzione per utilizzare lo shader specular</i></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(153, 0, 0);font-family:arial;font-size:100%;" > </span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">private</span><span style="color: rgb(255, 102, 51);"> void</span> DrawModelSpecular<span style="color: rgb(102, 51, 0);"><b>(</b></span>Model model<span style="color: rgb(102, 51, 0);"><b>,</b></span> Matrix world<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMesh mesh in model<span style="color: rgb(102, 51, 0);"><b>.</b></span>Meshes<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMeshPart part in mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>MeshParts<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > part<span style="color: rgb(102, 51, 0);"><b>.</b></span>Effect<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> effect<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > worldInverseTransposeMatrix<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transpose<span style="color: rgb(102, 51, 0);"><b>(</b></span>Matrix<span style="color: rgb(102, 51, 0);"><b>.</b></span>Invert<span style="color: rgb(102, 51, 0);"><b>(</b></span>mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> world<span style="color: rgb(102, 51, 0);"><b>));</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"WorldInverseTranspose"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>worldInverseTransposeMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"ViewVector"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>viewVector<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"World"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>world<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"View"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ViewMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" > effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"Projection"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ProjectionMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>Draw<span style="color: rgb(102, 51, 0);"><b>();</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" ><b>}</b></span><span style="font-size:100%;">
<br /></span></pre>
<br /><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>Caricamento del modello e Camera 3d:</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Per questo tutorial non ho usato il model manager che abbiamo creato nelle scorse lezioni (Sarebbe stato scomodo presentare la gestione degli shader... e vorrei fare in modo che anche
<br />chi non fosse interessato alle altre lezioni possa comunque leggere e seguire il post).</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La logica per caricare il modello è molto semplice:</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >1) nella funzione LoadContent carico il modello e gestisco le informazione sulle bones</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >2) nella funzione Draw richiamo la funzione DrawAmbient che si occupa di scorrere le componenti della mesh e renderizzarle utilizzando il nostro materiale. </span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >3) nella funzione update incrementiamo il valore angle, che verrà adottato insieme alla funzione createRotationY per costruire la matrice world e far ruotare l'oggetto.</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La camera che ho utilizzato è la QuakeCamera (prelevata pari pari dal libro xna 3.0 game programming recipes) che viene istanziata nella funzione initialize ricevendo come secondo paramentro la posizione della camera.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Nella funzione Update passeremo alla camera le informazioni relative agli input(keyboard, mouse, gamepad) permettendo alla classe di ricostruire la nuova posizione e la nuova matrice View. </span><span style="font-size:100%;">
<br />
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><b>Effect:</b></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ora che abbiamo visto come viene caricato il modello, possiamo tornare allo scopo del post, gli shader. </span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Prima di tutto per creare un file fx dovete aggiungere il file nella vostra cartella content (io ho creato una cartella effect che ospiterà questi e i prossimi effetti che vi racconterò). </span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Per aggiungere l'effetto cliccate nella gestione file del progetto e "Add New Item" quindi scegliete file .fx.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Il caricamento di un file effect utilizza la funzione Load della pipeline xna, posizioniamo la funzione nella LoadContent:</span><span style="font-size:100%;">
<br />
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect = Content.Load("<span style="color: rgb(51, 204, 0);">effect/Ambient</span>")</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ora facciamo una passo indietro.. nel blocco 1) del file Ambient.fx abbiamo parlato di alcune variabili da definire attraverso l'applicazione:</span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">extern</span> float4x4 World<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">extern</span> float4x4 View<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="color: rgb(153, 0, 0);">extern</span> float4x4 Projection<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >La voce extern serve proprio ad indicare che queste variabili sono definite tramite un processo esterno al file, ed è quello che faremo nella funzione drawAmbient:</span><span style="font-size:100%;">
<br />
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >foreach<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>(</b></span>ModelMeshPart part in mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>MeshParts<span style="color: rgb(102, 51, 0);"><b>)</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>{</b></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >part<span style="color: rgb(102, 51, 0);"><b>.</b></span>Effect<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>=</b></span> effect<span style="color: rgb(102, 51, 0);"><b>;</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"World"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>world<span style="color: rgb(102, 51, 0);"> </span><span style="color: rgb(102, 51, 0);"><b>*</b></span> mesh<span style="color: rgb(102, 51, 0);"><b>.</b></span>ParentBone<span style="color: rgb(102, 51, 0);"><b>.</b></span>Transform<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"View"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ViewMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /><span style="font-family:arial;"> </span></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >effect<span style="color: rgb(102, 51, 0);"><b>.</b></span>Parameters<span style="color: rgb(102, 51, 0);"><b>[</b></span><span style="color: rgb(0, 153, 0);">"Projection"</span><span style="color: rgb(102, 51, 0);"><b>].</b></span>SetValue<span style="color: rgb(102, 51, 0);"><b>(</b></span>fpsCam<span style="color: rgb(102, 51, 0);"><b>.</b></span>ProjectionMatrix<span style="color: rgb(102, 51, 0);"><b>);</b></span></span><span style="font-size:100%;">
<br /></span><span style="color: rgb(102, 51, 0);font-family:arial;font-size:100%;" > <b>}</b></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" ><span style="font-weight: normal;">Per ogni </span><b>Mesh</b> destineremo alle varie<b> parti </b> l'effetto ambient e imposteremo i parametri dell'effetto tramite la funzione setValue(); Quindi i valori World View e Projection andranno in automatico a
<br />valorizzare le variabili dichiarate extern a inizio codice ambient.fx. </span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Tutto qui! :D </span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >I codici che incorporerò a fondo articolo comprendo già altri 2 materiali (Specular e Diffuse) che vedremo nei prossimi post.</span><span style="font-size:100%;">
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Voi potete iniziare a testarli modificando la chiamata alla funzione che si occupa di disegnare il modello (seguite i commenti nella funzione draw)
<br /></span><span style=";font-family:arial;font-size:100%;" ><span>
<br />
<br />Questo è il risultato che otterete lanciando il codice:
<br />
<br /></span></span><span style="font-size:100%;"><a style="font-family: arial;" onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3xNnDoqXbHSdyLatoubrP384Soa68IMPJGJ4YBA3gr9onXDGLssbURrz653-cCoK6TJrxEGujjaEAmLUrGV4_ermtBN1Vi5YQyj8F_n8UlLg-62dzNephwBuQcO59E7sqnOMeQTuy3hg/s1600-h/Senza-titolo-2.jpg"><img style="cursor: pointer; width: 400px; height: 299px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh3xNnDoqXbHSdyLatoubrP384Soa68IMPJGJ4YBA3gr9onXDGLssbURrz653-cCoK6TJrxEGujjaEAmLUrGV4_ermtBN1Vi5YQyj8F_n8UlLg-62dzNephwBuQcO59E7sqnOMeQTuy3hg/s400/Senza-titolo-2.jpg" alt="" id="BLOGGER_PHOTO_ID_5391480813315180610" border="0" /></a>
<br /></span><span style=";font-family:arial;font-size:100%;" ><span>
<br />brutto forte eh?...bhe diciamo che non è cool come le altre volte :P però siamo alle basi dell'HLSL.. andando avanti magari uscirà qualcosa di più interessante!!
<br />
<br /></span></span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Direi che è tutto... non esitate a fare domande nel caso in cui ci fossero passaggi poco chiari ! </span><span style="font-size:100%;">
<br />
<br /></span><span style=";font-family:Arial,sans-serif;font-size:100%;" >Ciao! Alla prossima</span><span style="font-size:100%;">
<br />
<br /></span><span style="font-family:Arial,sans-serif;"><span style="font-size:85%;"><span style="font-size:100%;"><b style="font-family: arial;">Yari
<br />
<br />Sorgenti:
<br /></b><a style="font-weight: bold; font-family: arial;" href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.4.hlsl.zip"><span style="color: rgb(255, 153, 0);">imparandoxna_3d.4.hlsl.zip</span></a></span><b><span style="font-size:100%;">
<br /></span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_hlsl.pdf"><span style="color: rgb(255, 153, 0);">Lezione in PDF </span></a>
<br />
<br /></b></span></span>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com7tag:blogger.com,1999:blog-1511468527759599388.post-34210056937618430302009-09-28T13:01:00.000-07:002009-09-28T13:11:01.017-07:00Si ricomincia!Ciao a tutti!<br />Dopo un abbondante silenzio, ho deciso di riprendere in mano il blog e scrivere qualcosa di nuovo.<br />Sto preparando un tutorial sul post processing dove farò vedere come dare un pò di blur alla nostra astronave.... credo di avere il tempo per postare già da settimana prossima! <br /><br />Grazie a tutti per aver visitato il blog anche durante questi mesi di buio totale!!! <br />A prestissimo!<br /><br />xna@fastwebnet.itYari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com3tag:blogger.com,1999:blog-1511468527759599388.post-38939989340404499302009-04-28T15:22:00.000-07:002011-10-05T00:44:37.710-07:003D.4) Xna tutorial 3d: Creare una camera FPSNello scorso articolo avete visto come si carica un modello 3d, ora sfrutteremo lo stesso codice apportando qualche modifica alla camera per imparare a gestire un modello di navigazione della scena simile a quello delle camera FPS (first person shooter).<br /><br /><span style="font-weight:bold;">Anteprima Video:</span><br /><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/u0LJhHpI62o&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/u0LJhHpI62o&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object><br />Prendete i codici sorgenti a fondo pagina o utilizzate quelli della scorsa "lezione".<br /><br />Quello che vogliamo fare è aggiungere alla camera delle informazioni di posizione dinamiche, fare in modo quindi che tramite determinati eventi (presisone di tasti e spostamento del mouse) la camera cambi posizione e direzione.<br /><br />Prima id mostrarvi il codice della camera vi descrivo quali sono le legiche che andremo ad implementare:<br /><br />Una prima modifica rispetto alla camera base vista negli scorsi post, sta nel identificare una <span style="font-weight: bold;">direzione</span> verso la quale la camera punta.<br /><br />Fino ad ora abbiamo avuto a che fare solo con il target e la posizione della camera, ora tramite una semplice sottrazione di vettori andremo a definire la <span style="font-weight: bold;">direzione = targetCamera - posizioneCamera</span>.<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggBR9B1gRCCvYq4W232IP_l8qdjP7wvZlUlJWrmEA_y2qvoHb7j-nAnHYFBzGdUtT4puM-CSdf0iaw5Z4qel6jpuxN7nOX4Pfq3X6ycbp5A5Ls1DUKpbpKW_a7bIG_Dgrgdqe78lozn0E/s1600-h/ast-363.gif"><img style="cursor: pointer; width: 313px; height: 186px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEggBR9B1gRCCvYq4W232IP_l8qdjP7wvZlUlJWrmEA_y2qvoHb7j-nAnHYFBzGdUtT4puM-CSdf0iaw5Z4qel6jpuxN7nOX4Pfq3X6ycbp5A5Ls1DUKpbpKW_a7bIG_Dgrgdqe78lozn0E/s400/ast-363.gif" alt="" id="BLOGGER_PHOTO_ID_5329875361244537618" border="0" /></a><br /><span style="font-weight: bold;">Esempio: </span><br />Guardando l'immagine sopra diciamo che :<br />- il punto dal quale partono i vettori è il nostro punto (0,0,0) origine<br />- il vettore a è la posizione della camera [esempio (2,3,0)]<br />- il vettore a + b è il target della camera [esempio (7,3,0)]<br />- il vettore b è la direzione della camera [esempio (5,0,0)]<br /><br /><span style="font-weight: bold;">Come calcoliamo la spostamento della camera?</span><br />Associando alla pressione di uno dei tasti classici per una camera FPS (w,a,s,d), un movimento della camera nello spazio.<br /><br />Per mantenere gli spostamenti uniformi, prima di tutto rendiamo il vettore direzione "normalizzato" ovvero poniamolo sempre di lunghezza 1.<br />I tasti <span style="font-weight: bold;">W e S </span>faranno muovere la camera di una "unità" nella direzione attuale (in avanti o indietro).<br /><span style="font-style: italic;">Nel caso dell'esempio di prima, la camera posizionata in a-> si sposterà lungo la proiezione di b-> su a-> ad ogni ciclo update. Quindi l'asse che determina lo spostamento è quello definito dalla direzione della camera.</span><br />Il movimento dei tasti<span style="font-weight: bold;"> A e D</span> richiede un pò di calcoli in più:<br />Per definire lo spostamento laterale della camera dovremo eseguire il prodotto cross (in italiano <a href="http://it.wikipedia.org/wiki/Prodotto_vettoriale">prodotto vettoriale</a>) del vettore che identifica il verso Up della camera e la direzione. Questo prodotto genera il vettore (l'asse) laterale della camera. <span style="font-style: italic;">Quindi la camera si sposterà sul prodotto vettoriale del vettore Up con il vettore direzione.</span><br />Se non conoscete il prodotto cross non preoccupatevi, esiste una funzione predefinita di xna che eseguirà il calcolo per noi(l'importante per ora è capire la logica).<br /><br /><span style="font-weight: bold;">Le formule di spostamento:</span><br /><span style="font-style: italic;">Spostamento avanti (W)</span><br />posizioneCamera += Direzione<br /><br /><span style="font-style: italic;">Spostamento indietro (S)</span><br />posizioneCamera -= Direzione<br /><br /><br /><span style="font-style: italic;">Spostamento destra (D)</span><br /> posizioneCamera -= ProdottoCross(Direzione,Up)<br /><br /><span style="font-style: italic;">Spostamento Sinistra (A)</span><br /> posizioneCamera += ProdottoCross(Direzione,Up)<br /><br /><span style="font-weight: bold;">Come calcoliamo le Rotazioni della camera ?</span><br />In questo caso per definire una rotazione dobbiamo prima capire quale asse interviene nel calcolare l'angolo di spostamento dell'obbiettivo in base agli spostamenti del mouse.<br /><span style="font-style: italic;"></span><br />Muovendo<span style="font-weight: bold;"> il mouse a destra o sinistra</span> vogliamo che la camera ruoti<span style="font-style: italic;"> sull'asse Y (movimento yaw)</span><br />mentre muovendo<span style="font-weight: bold;"> il mouse avanti o indietro </span>la camera deve ruotare sull'asse laterale della camera, il prodotto vettoriale tra Up e Direzione (<span style="font-style: italic;">movimento Pitch</span>)<br /><br />In entrambi i casi il vettore che subirà modifiche sarà il vettore direzione e nel caso del movimento Pitch verrà modificato anche il vettore Up. (Provate a simulare con le mani la rotazione della camera usando il pollice come vettore UP e L'indice come Direzione mettendoli perpendicolari tra di loro)<br /><br /><span style="font-weight: bold;">Le formule di rotazione:</span><br /><span style="font-style: italic;">Rotazione Yaw</span><br />Direzione +-= Rotazione di direzione sull'asse Up * spostamento del mouse (destra o sinistra)<br /><br /><span style="font-style: italic;">Rotazione Pitch</span><br />Direzione +-= Rotazione di Direzione sull'asse (Up*Direzione) * spostamento del mouse (avanti o indietro )<br />Up +-= Rotazione di Up sull'asse (Up*Direzione) * spostamento del mouse (avanti o indietro)<br /><br />A questo punto non resta che incollare qui il codice della camera:<br /><br /><span style="font-weight: bold;">FPSCAMERA.cs</span><br /><pre><span style="color:#990000;">using</span> System<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> System<b><span style="color:#663300;">.</span></b>Collections<b><span style="color:#663300;">.</span></b>Generic<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> System<b><span style="color:#663300;">.</span></b>Linq<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Audio<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Content<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>GamerServices<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Graphics<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Input<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Media<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Net<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Storage<b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br /><br /><br />namespace</span> imparandoxna_3dmodello<b><span style="color:#663300;"><br />{</span></b><i><span style="color:#999999;"><br /> /// <summary><br /> /// This is a game component that implements IUpdateable.<br /> /// </summary><br /></span></i><span style="color:#990000;"> public class</span> FPSCamera<b><span style="color:#663300;"> :</span></b> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>GameComponent<b><span style="color:#663300;"><br /> {</span></b><span style="color:#990000;"><br /> <br /> public</span> Matrix view<b><span style="color:#663300;"> {</span></b> get<b><span style="color:#663300;">;</span></b><span style="color:#990000;"> protected</span> set<b><span style="color:#663300;">; }</span></b><span style="color:#990000;"><br /> public</span> Matrix projection<b><span style="color:#663300;"> {</span></b> get<b><span style="color:#663300;">;</span></b><span style="color:#990000;"> protected</span> set<b><span style="color:#663300;">; }</span></b><span style="color:#990000;"><br /><br /> public</span> Vector3 cameraPosition<b><span style="color:#663300;"> {</span></b> get<b><span style="color:#663300;">;</span></b><span style="color:#990000;"> protected</span> set<b><span style="color:#663300;">; }</span></b><br /> Vector3 cameraDirection<b><span style="color:#663300;">;</span></b><br /> Vector3 cameraUp<b><span style="color:#663300;">;</span></b><br /><br /> MouseState prevMouseState<b><span style="color:#663300;">;</span></b><span style="color:#ff6633;"><br /> float</span> speed<b><span style="color:#663300;"> =</span></b><span style="color:#996600;"> 1.5f</span><b><span style="color:#663300;">;</span></b><span style="color:#990000;"><br /><br /><br /> public</span> FPSCamera<b><span style="color:#663300;">(</span></b>Game game<b><span style="color:#663300;">,</span></b>Vector3 pos<b><span style="color:#663300;">,</span></b> Vector3 target<b><span style="color:#663300;">,</span></b> Vector3 up<b><span style="color:#663300;">)<br /> :</span></b> base<b><span style="color:#663300;">(</span></b>game<b><span style="color:#663300;">)<br /> {</span></b><i><span style="color:#999999;"><br /> //Inizializzo varaibili di posizione<br /></span></i> cameraPosition<b><span style="color:#663300;"> =</span></b> pos<b><span style="color:#663300;">;</span></b><br /> cameraDirection<b><span style="color:#663300;"> =</span></b> target<b><span style="color:#663300;"> -</span></b> pos<b><span style="color:#663300;">;</span></b><br /> cameraDirection<b><span style="color:#663300;">.</span></b>Normalize<b><span style="color:#663300;">();</span></b><br /> cameraUp<b><span style="color:#663300;"> =</span></b> up<b><span style="color:#663300;">;</span></b><i><span style="color:#999999;"><br /> <br /> //Rigenero la variabile view<br /></span></i> FPSCreateLookAt<b><span style="color:#663300;">();</span></b><i><span style="color:#999999;"><br /> <br /> //Inizializzo projection<br /></span></i> projection<b><span style="color:#663300;"> =</span></b> Matrix<b><span style="color:#663300;">.</span></b>CreatePerspectiveFieldOfView<b><span style="color:#663300;">(</span></b><br /> MathHelper<b><span style="color:#663300;">.</span></b>PiOver4<b><span style="color:#663300;">,<br /> (</span></b><span style="color:#ff6633;">float</span><b><span style="color:#663300;">)</span></b>Game<b><span style="color:#663300;">.</span></b>Window<b><span style="color:#663300;">.</span></b>ClientBounds<b><span style="color:#663300;">.</span></b>Width<b><span style="color:#663300;"> /<br /> (</span></b><span style="color:#ff6633;">float</span><b><span style="color:#663300;">)</span></b>Game<b><span style="color:#663300;">.</span></b>Window<b><span style="color:#663300;">.</span></b>ClientBounds<b><span style="color:#663300;">.</span></b>Height<b><span style="color:#663300;">,</span></b><span style="color:#999900;"><br /> 1</span><b><span style="color:#663300;">,</span></b><span style="color:#999900;"> 3000</span><b><span style="color:#663300;">);<br /> }</span></b><span style="color:#990000;"><br /><br /> public</span> override<span style="color:#ff6633;"> void</span> Initialize<b><span style="color:#663300;">()<br /> {</span></b><i><span style="color:#999999;"><br /> // TODO: Add your initialization code here<br /></span></i> Mouse<b><span style="color:#663300;">.</span></b>SetPosition<b><span style="color:#663300;">(</span></b>Game<b><span style="color:#663300;">.</span></b>Window<b><span style="color:#663300;">.</span></b>ClientBounds<b><span style="color:#663300;">.</span></b>Width<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 2</span><b><span style="color:#663300;">,</span></b> Game<b><span style="color:#663300;">.</span></b>Window<b><span style="color:#663300;">.</span></b>ClientBounds<b><span style="color:#663300;">.</span></b>Height<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 2</span><b><span style="color:#663300;">);</span></b><br /> prevMouseState<b><span style="color:#663300;"> =</span></b> Mouse<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">();</span></b><br /> base<b><span style="color:#663300;">.</span></b>Initialize<b><span style="color:#663300;">();<br /> }</span></b><span style="color:#990000;"><br /><br /> public</span> override<span style="color:#ff6633;"> void</span> Update<b><span style="color:#663300;">(</span></b>GameTime gameTime<b><span style="color:#663300;">)<br /> {</span></b><span style="color:#ff0000;"><br /> if</span><b><span style="color:#663300;"> (</span></b>Keyboard<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>IsKeyDown<b><span style="color:#663300;">(</span></b>Keys<b><span style="color:#663300;">.</span></b>Space<b><span style="color:#663300;">))<br /> {</span></b><br /> Mouse<b><span style="color:#663300;">.</span></b>SetPosition<b><span style="color:#663300;">(</span></b>Game<b><span style="color:#663300;">.</span></b>Window<b><span style="color:#663300;">.</span></b>ClientBounds<b><span style="color:#663300;">.</span></b>Width<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 2</span><b><span style="color:#663300;">,</span></b> Game<b><span style="color:#663300;">.</span></b>Window<b><span style="color:#663300;">.</span></b>ClientBounds<b><span style="color:#663300;">.</span></b>Height<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 2</span><b><span style="color:#663300;">);</span></b><br /> prevMouseState<b><span style="color:#663300;"> =</span></b> Mouse<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">();<br /> }</span></b><i><span style="color:#999999;"><br /> <br /> // Spostamento Aventi indietro<br /></span></i><span style="color:#ff0000;"> if</span><b><span style="color:#663300;"> (</span></b>Keyboard<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>IsKeyDown<b><span style="color:#663300;">(</span></b>Keys<b><span style="color:#663300;">.</span></b>W<b><span style="color:#663300;">)) {</span></b><br /> cameraPosition<b><span style="color:#663300;"> +=</span></b> cameraDirection<b><span style="color:#663300;"> *</span></b> speed<b><span style="color:#663300;">;<br /> }</span></b><span style="color:#ff0000;"><br /> if</span><b><span style="color:#663300;"> (</span></b>Keyboard<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>IsKeyDown<b><span style="color:#663300;">(</span></b>Keys<b><span style="color:#663300;">.</span></b>S<b><span style="color:#663300;">))<br /> {</span></b><br /> cameraPosition<b><span style="color:#663300;"> -=</span></b> cameraDirection<b><span style="color:#663300;"> *</span></b> speed<b><span style="color:#663300;">;<br /> }</span></b><i><span style="color:#999999;"><br /><br /> // Spostamento Destra Sinistra<br /></span></i><span style="color:#ff0000;"> if</span><b><span style="color:#663300;"> (</span></b>Keyboard<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>IsKeyDown<b><span style="color:#663300;">(</span></b>Keys<b><span style="color:#663300;">.</span></b>A<b><span style="color:#663300;">))<br /> {</span></b><br /> cameraPosition<b><span style="color:#663300;"> +=</span></b> Vector3<b><span style="color:#663300;">.</span></b>Cross<b><span style="color:#663300;">(</span></b>cameraUp<b><span style="color:#663300;">,</span></b>cameraDirection<b><span style="color:#663300;">) *</span></b> speed<b><span style="color:#663300;">;<br /> }</span></b><span style="color:#ff0000;"><br /> if</span><b><span style="color:#663300;"> (</span></b>Keyboard<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>IsKeyDown<b><span style="color:#663300;">(</span></b>Keys<b><span style="color:#663300;">.</span></b>D<b><span style="color:#663300;">))<br /> {</span></b><br /> cameraPosition<b><span style="color:#663300;"> -=</span></b> Vector3<b><span style="color:#663300;">.</span></b>Cross<b><span style="color:#663300;">(</span></b>cameraUp<b><span style="color:#663300;">,</span></b> cameraDirection<b><span style="color:#663300;">) *</span></b> speed<b><span style="color:#663300;">;<br /> }</span></b><i><span style="color:#999999;"><br /><br /> //Rotazione sulla Y<br /></span></i> cameraDirection<b><span style="color:#663300;"> =</span></b> Vector3<b><span style="color:#663300;">.</span></b>Transform<b><span style="color:#663300;">(</span></b>cameraDirection<b><span style="color:#663300;">,</span></b><br /> Matrix<b><span style="color:#663300;">.</span></b>CreateFromAxisAngle<b><span style="color:#663300;">(</span></b>cameraUp<b><span style="color:#663300;">, (-</span></b>MathHelper<b><span style="color:#663300;">.</span></b>PiOver4<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 150</span><b><span style="color:#663300;">) *<br /> (</span></b>Mouse<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>X<b><span style="color:#663300;"> -</span></b> prevMouseState<b><span style="color:#663300;">.</span></b>X<b><span style="color:#663300;">)));</span></b><i><span style="color:#999999;"><br /><br /> //Rotazione sulla Cross tra Direzione e UP<br /></span></i> cameraDirection<b><span style="color:#663300;"> =</span></b> Vector3<b><span style="color:#663300;">.</span></b>Transform<b><span style="color:#663300;">(</span></b>cameraDirection<b><span style="color:#663300;">,</span></b><br /> Matrix<b><span style="color:#663300;">.</span></b>CreateFromAxisAngle<b><span style="color:#663300;">(</span></b>Vector3<b><span style="color:#663300;">.</span></b>Cross<b><span style="color:#663300;">(</span></b>cameraUp<b><span style="color:#663300;">,</span></b>cameraDirection<b><span style="color:#663300;">),<br /> (-</span></b>MathHelper<b><span style="color:#663300;">.</span></b>PiOver4<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 150</span><b><span style="color:#663300;">) *<br /> (</span></b>prevMouseState<b><span style="color:#663300;">.</span></b>Y<b><span style="color:#663300;"> -</span></b> Mouse<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>Y<b><span style="color:#663300;">)));</span></b><br /><br /> cameraUp<b><span style="color:#663300;"> =</span></b> Vector3<b><span style="color:#663300;">.</span></b>Transform<b><span style="color:#663300;">(</span></b>cameraUp<b><span style="color:#663300;">,</span></b><br /> Matrix<b><span style="color:#663300;">.</span></b>CreateFromAxisAngle<b><span style="color:#663300;">(</span></b>Vector3<b><span style="color:#663300;">.</span></b>Cross<b><span style="color:#663300;">(</span></b>cameraUp<b><span style="color:#663300;">,</span></b> cameraDirection<b><span style="color:#663300;">),<br /> (-</span></b>MathHelper<b><span style="color:#663300;">.</span></b>PiOver4<b><span style="color:#663300;"> /</span></b><span style="color:#999900;"> 150</span><b><span style="color:#663300;">) *<br /> (</span></b>prevMouseState<b><span style="color:#663300;">.</span></b>Y<b><span style="color:#663300;"> -</span></b> Mouse<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">().</span></b>Y<b><span style="color:#663300;">)));</span></b><br /><br /> prevMouseState<b><span style="color:#663300;"> =</span></b> Mouse<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">();</span></b><i><span style="color:#999999;"><br /><br /> //Rigenero la view<br /></span></i> FPSCreateLookAt<b><span style="color:#663300;">();</span></b><br /> <br /> base<b><span style="color:#663300;">.</span></b>Update<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);<br /> }</span></b><span style="color:#990000;"><br /><br /> public</span><span style="color:#ff6633;"> void</span> FPSCreateLookAt<b><span style="color:#663300;">() {</span></b><br /> view<b><span style="color:#663300;"> =</span></b> Matrix<b><span style="color:#663300;">.</span></b>CreateLookAt<b><span style="color:#663300;">(</span></b>cameraPosition<b><span style="color:#663300;">,</span></b> cameraPosition<b><span style="color:#663300;"> +</span></b> cameraDirection<b><span style="color:#663300;">,</span></b> cameraUp<b><span style="color:#663300;">);<br /> }<br /> }<br />}</span></b></pre>L'unica cosa che non vi ho mostrato prima è la funzione FPSCreateLookAt() che si occupa di chiamare la funziona createLookAt per ricreare la matrice view della camera. Questa funzione va richiamata ogni volta che si vuole modificare / aggiornare la posizione della camera.<br />Rispetto alal camera standard sono state estrapolate le variabili di posizione, direzione, up e sono state messe come variabili di classe in modo da poter essere aggioranbili di volta in volta dall'update.<br />Un'ultima cosa da notare è la presenza di una variabile speed... immaginate a cosa serve? :P<br />Mentre il resto del codice è quanto vi ho descritto sopra.<br /><br />Ora ricordatevi di modificare le occorrenze della classe Camera in FPSCamera nel file game1.cs,<br />mentre nella classe model3d troverete giù un overloading della funzione Draw che accetta in ingresso una FPScamera invece che una Camera (le funzioni sono identiche cambia solo il parametro in ingresso).<br /><br /><span style="font-weight: bold;">Sorgenti</span><br /><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.3.zip">imparandoxna_3d.3.zip</a>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com6tag:blogger.com,1999:blog-1511468527759599388.post-20137326976628025652009-04-28T13:16:00.000-07:002011-10-05T00:45:07.112-07:003D.3) Xna tutorial 3d: Caricare un modello 3dIn attesa del nuovo sito preferisco iniziare a pubblicare qualche nuovo articolo. Il tempo e' tiranno e chissà quando riuscirò a buttarmi sullo sviluppo del nuovo spazio....per evitare di rimanere totalmente fermo, nel frattempo cerco di chiudere i tutorial relativi all'area 3d!
<br />
<br />Oggi vi mostro come caricare un semplice modello 3d, utilizzando un componente che avrà lo scopo di fare da manager e una classe model3d che rappresentarà il modello da caricare.
<br />
<br /><span style="font-weight: bold;">Modelli 3d:</span>
<br />Nell'ultimo post avete visto come disegnare una semplice forma e colorarla, come potete immaginare creare un'intera figura 3d complessa utilizzando le primitive è abbastanza scomodo... se non impossibile.
<br />
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRkNCV3P7KJmmMjone8eOIxUm41y6NHf2TWAJ9s7EojHnbKHxjwsoIzBvjRLsz5CCCfga0tm-7ALUGcNd5Oj7J-Ts1cPp0oADJflUzi4G45vd-mYfLmqyFVH0lVnwEgXa9PszocpUUL0Y/s1600-h/hdmodels_cars_vol_2_wireframe1.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 400px; height: 267px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiRkNCV3P7KJmmMjone8eOIxUm41y6NHf2TWAJ9s7EojHnbKHxjwsoIzBvjRLsz5CCCfga0tm-7ALUGcNd5Oj7J-Ts1cPp0oADJflUzi4G45vd-mYfLmqyFVH0lVnwEgXa9PszocpUUL0Y/s400/hdmodels_cars_vol_2_wireframe1.jpg" alt="" id="BLOGGER_PHOTO_ID_5329860838280334130" border="0" /></a>Esistono appositi tool per la creazione di modelli 3d complessi, ne cito solo alcuni :
<br />Maya, 3d Studio Max, XSI, Cinema4d , Sketchup....etc. La curva di apprendimento di questi strumenti non è ripidissima solitamente (almeno 3 o 4 mesi fatti bene ci vogliono però...), per produrre dei bei modelli dovrete però smanettare parecchio (non parliamo poi del discorso animazione....).
<br />Io per ora sto utilizzando dei modelli fatti in sketchup e convertiti in directx , dato che il formato di sketchup non è letto dalla pipeline di xna.
<br />
<br />
<br />Prima di tutto posto il link dal quale ho reperito il modello per questo tutorial:
<br /><a href="http://sketchup.google.com/3dwarehouse/details?mid=e2eec1928fca478b339bd6b570381585">Sketchup warehouse</a>, qui potete trovere una bellissima gallery di modelli di Battlestar Galactica :D.
<br />Il formato sketchup può essere convertito in directx tramite questo<a href="http://www.3drad.com/Google-SketchUp-To-DirectX-XNA-Exporter-Plug-in.htm"> plugin </a>(sul sito trovate tutte le info necessarie, tranne l'esportazione dei materiali. Vi spiego al volo che per esportare una texture dovrete aprire la finestra materiali di sketchup, cliccare sulla texture con il tasto destro e salvarla in formato immagine. Ora nel vostro directx cercate a fondo file il punto nel quale viene definita la texture (solitamente .tga se esportato da sketchup)
<br /><span style="font-style: italic;">TextureFilename { "COLCOL1C.tga"; }</span> e rinominatela con estensione e nome della texture salvato qualche step prima (dalla finestra materiali esportate in jpg... non fatevi fregare e corregete l'estensione presente nel directx altrimenti in fase compilazione del modello si generano errori).
<br />
<br /><span style="font-weight: bold;">Camera:</span>
<br />Prima di tutto ci servirà una camera, quella del post precedente va benissimo, importatela tra i file del vostro nuovo progetto (Tasto destro sul solution explorer aggiungede un "existing item" e cercare la classe camera.cs del vecchio tutorial. Cambiate il namespace con lo stesso che state utilizzando per il nuovo progetto).
<br />
<br /><span style="font-weight: bold;">Anatomia di un modello 3d:</span>
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKn-eOJf5dNvvZ6eLpLOuiFl-j207AXq7VeJvGadzogziafQaZj3ED6bUjpJ5RPZ_HJ2KFag-8h_ozmFQg8MHZ6A4qKp0SAHAb1c3xKl5zerGnd4bHZ_S6knkc989r99kbXYC4Z671eJw/s1600-h/9780596521950.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 95px; height: 126px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhKn-eOJf5dNvvZ6eLpLOuiFl-j207AXq7VeJvGadzogziafQaZj3ED6bUjpJ5RPZ_HJ2KFag-8h_ozmFQg8MHZ6A4qKp0SAHAb1c3xKl5zerGnd4bHZ_S6knkc989r99kbXYC4Z671eJw/s400/9780596521950.jpg" alt="" id="BLOGGER_PHOTO_ID_5329862167308509698" border="0" /></a>Come dice Aaron Reed nel libro "Learning XNA 3.0" (che come vi dicevo, è il libro dal quale sto studiando XNA ... :P faccio un pò di pubblicità dato che sto usando tantissimo di quello che imparo per scrivere questi post!) <span style="font-style: italic;">"Per capire come disegnare un modello in xna bisogna prima capire come è composto".
<br /><span style="font-style: italic;"></span></span>
<br />Un modello3d contiene uno o più oggetti chiamati <span style="font-weight: bold;">mesh</span> , rappresentati tramite XNA dalla classe <span style="font-weight: bold;">ModelMesh</span>, un Mesh a sua volta contiene colori o texture storizzate in altri oggetti presenti all'interno di ogni mesh. Queste parti sono identificate da oggetti di tipo <span style="font-weight: bold;">ModelMeshPart</span>.
<br />Ogni MeshPart di un ModelMesh quindi contiene i materiali e gli effetti attraverso i quali disegnare le mesh.
<br />
<br />Ora dato che si è creata una gerarchia di informazioni un pò complessa, riassumiamo:
<br />
<br /><span style="font-weight: bold;">Modello</span> (che non vi ho ancora detto, è identificato dalla classe <span style="font-weight: bold;">Model</span>)
<br />---|
<br />---|_____<span style="font-weight: bold;">Mesh</span> (Classe ModelMesh)
<br /> -----------|
<br /> -----------|_____<span style="font-weight: bold;">MeshParts</span> (Classe ModelMeshParts)
<br /> ----------------------|
<br /> ----------------------|____<span style="font-weight: bold;">Materiali/Effects</span>
<br />
<br />Un esempio potrebbe essere la rappresentazione di una macchina:
<br />Avremmo un modello composto da 2 mesh, la carrozzeria e le ruote. Ogni mesh avrebbe il suo specifico materiale posizionato nelle meshParts.
<br />
<br />Per quanto riguarda gli effects, ricordate che di default viene utilizzato un effetto chiamato "BasicEffect" che ha già delle impostazioni molto semplici che vi permettono di renderizzare modelli senza troppa fatica e senza dover scrivere alcun HLSL ( high level shadare language, il linguaggio utilizzato in direct x per la generazione dei materiali ...come già accennato nel blog, farò un post appositamente dedicato a questo argomento).
<br />
<br />Passiamo quindi al codice:
<br />Prima di tutto aggiungete una nuova classe e chiamatela model3d.cs
<br /><span style="font-weight: bold;">Vi sconsiglio di fare copia e incolla direttamente da qui.... usate sempre i sorgenti presenti a fondo articolo!!</span>
<br />
<br /><span style="font-weight: bold;">MODEL3D</span>:
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />namespace</span> imparandoxna_3dmodello<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br />class</span> model3d<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br />public</span> Model model<b><span style="color: rgb(102, 51, 0);"> {</span></b> get<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"> protected</span> set<b><span style="color: rgb(102, 51, 0);">; }</span></b><span style="color: rgb(153, 0, 0);">
<br />protected</span> Matrix world<b><span style="color: rgb(102, 51, 0);"> =</span></b> Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>Identity<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span> model3d<b><span style="color: rgb(102, 51, 0);">(</span></b>Model m<b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br />model<b><span style="color: rgb(102, 51, 0);"> =</span></b> m<b><span style="color: rgb(102, 51, 0);">;
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public virtual</span><span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">() {
<br />
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span><span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>Camera camera<b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br />Matrix<b><span style="color: rgb(102, 51, 0);">[]</span></b> transorms<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Matrix<b><span style="color: rgb(102, 51, 0);">[</span></b>model<b><span style="color: rgb(102, 51, 0);">.</span></b>Bones<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">];</span></b>
<br />model<b><span style="color: rgb(102, 51, 0);">.</span></b>CopyAbsoluteBoneTransformsTo<b><span style="color: rgb(102, 51, 0);">(</span></b>transorms<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br />foreach<b><span style="color: rgb(102, 51, 0);">(</span></b>ModelMesh mesh in model<b><span style="color: rgb(102, 51, 0);">.</span></b>Meshes<b><span style="color: rgb(102, 51, 0);">){</span></b>
<br /> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>BasicEffect be in mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>Effects<b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>EnableDefaultLighting<b><span style="color: rgb(102, 51, 0);">();</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>Projection<b><span style="color: rgb(102, 51, 0);"> =</span></b> camera<b><span style="color: rgb(102, 51, 0);">.</span></b>projection<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>View<b><span style="color: rgb(102, 51, 0);"> =</span></b> camera<b><span style="color: rgb(102, 51, 0);">.</span></b>view<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>World<b><span style="color: rgb(102, 51, 0);"> =</span></b> GetWorld<b><span style="color: rgb(102, 51, 0);">() *</span></b> mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>ParentBone<b><span style="color: rgb(102, 51, 0);">.</span></b>Transform<b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b>
<br /> mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">();
<br />}
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public virtual</span> Matrix GetWorld<b><span style="color: rgb(102, 51, 0);">() {</span></b><span style="color: rgb(255, 0, 0);">
<br />return</span> world<b><span style="color: rgb(102, 51, 0);">;
<br />}
<br />}
<br />}</span></b></pre>
<br />Questa classe ci permetterà di rappresentare e disegnare un modello 3d.
<br />al costruttore viene inviato direttamente un oggetto di tipo Model (oggetto base di XNA che dopo vedremo come caricare nella pipeline) e la funzione DRAW si occupa di scorrere la gerarchia che abbiamo visto prima eseguendo alcune operazioni utili al disegno dell'oggetto, ricevendo in ingresso la camera attuale.
<br />
<br /><pre> Matrix<b><span style="color: rgb(102, 51, 0);">[]</span></b> transforms<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Matrix<b><span style="color: rgb(102, 51, 0);">[</span></b>model<b><span style="color: rgb(102, 51, 0);">.</span></b>Bones<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">];</span></b>
<br />model<b><span style="color: rgb(102, 51, 0);">.</span></b>CopyAbsoluteBoneTransformsTo<b><span style="color: rgb(102, 51, 0);">(</span></b>transforms<b><span style="color: rgb(102, 51, 0);">);
<br />
<br /></span></b></pre> Queste chiamate servono per posizionare ogni mesh nella giusta posizione per far si ceh il modello sia correttamente composto.
<br /><pre> foreach<b><span style="color: rgb(102, 51, 0);">(</span></b>ModelMesh mesh in model<b><span style="color: rgb(102, 51, 0);">.</span></b>Meshes<b><span style="color: rgb(102, 51, 0);">){</span></b>
<br /> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>BasicEffect be in mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>Effects<b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>EnableDefaultLighting<b><span style="color: rgb(102, 51, 0);">();</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>Projection<b><span style="color: rgb(102, 51, 0);"> =</span></b> camera<b><span style="color: rgb(102, 51, 0);">.</span></b>projection<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>View<b><span style="color: rgb(102, 51, 0);"> =</span></b> camera<b><span style="color: rgb(102, 51, 0);">.</span></b>view<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> be<b><span style="color: rgb(102, 51, 0);">.</span></b>World<b><span style="color: rgb(102, 51, 0);"> =</span></b> GetWorld<b><span style="color: rgb(102, 51, 0);">() *</span></b> mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>ParentBone<b><span style="color: rgb(102, 51, 0);">.</span></b>Transform<b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b>
<br /> mesh<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">();
<br />}</span></b></pre> Qui invece scorriamo le famose mesh e per ogni mesh utilizziamo i loro effetti (in qeusto caso utilizziamo solo gli effetti basic. (Sinceramente pensavo di dover scorrere anche le ModelMeshParts di ogni ModelMesh.... ma vedo che in molti tutorial gli effetti vengono presi direttamente dai ModelMesh....uhm... x?X).
<br />Ogni mesh a questo punto passa all'effetto le informazioni di posizione e definizione della camera (view e projection) e infine chiama la funzione getWorld per restituire le informazioni di posizionamento della mesh nel "mondo".....che in questo caso sarà semplicemente una chiamata ad una matrice indentità quindi non vengono spostate dalla loro posizione originale. Se volessimo modificare informazioni posizionali degli oggetti creati con questa classe, dovremmo aggiungere un metodo update e modificare in questo punto la matrice World.
<br />
<br /><span style="font-weight: bold;">Come importare un modello:</span>
<br />Tasto destro su Content nella solution explorer, aggiungete un "existing item" e caricate il modello presente nei sorgenti (file .x). Ricordatevi di spostare la texture nella cartella content (proprio nella cartella eh! non tramite il solution explorer) del progetto (esempio c:/doc/visualc#/xna/questotutorial/content).
<br />Sotto alla solution explorer, cliccando sul file .x importato, dovreste vedere una finestra descrittiva che riporto qui :
<br />
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhyphenhyphenuJ40u5xUaMuguWsy5Qw8ZDpKbxjSmBP6-Z-xu0pfjmLAaZP_xG0abWTmZ4JW_MEQoM4CSuGymV2qOeAoiYSL6ahMyU6SqdBXv0TVp509g0PVor3WLgQTSpYrvGp3JIxJAIjKsszCu0/s1600-h/descr.jpg"><img style="cursor: pointer; width: 338px; height: 352px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjhyphenhyphenuJ40u5xUaMuguWsy5Qw8ZDpKbxjSmBP6-Z-xu0pfjmLAaZP_xG0abWTmZ4JW_MEQoM4CSuGymV2qOeAoiYSL6ahMyU6SqdBXv0TVp509g0PVor3WLgQTSpYrvGp3JIxJAIjKsszCu0/s400/descr.jpg" alt="" id="BLOGGER_PHOTO_ID_5329859271848759938" border="0" /></a>
<br />
<br />Ho modificato la voce <span style="font-weight: bold;">Asset Name</span> mettendo qualcosa di più semplice da raggiungere (dopo capirete perchè).
<br />
<br />Qui sotto il codice per il componente che gestisce i modelli creati dalla classe model3d.
<br />
<br /><span style="font-weight: bold;">MODELMANAGER.cs
<br /></span><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Audio<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GamerServices<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Media<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Net<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Storage<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />
<br />namespace</span> imparandoxna_3dmodello<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br />public class</span> ModelManager<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawableGameComponent<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b>
<br />List<b><span style="color: rgb(102, 51, 0);"><</span></b>model3d<b><span style="color: rgb(102, 51, 0);">></span></b> models<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> List<b><span style="color: rgb(102, 51, 0);"><</span></b>model3d<b><span style="color: rgb(102, 51, 0);">>();</span></b><span style="color: rgb(153, 0, 0);">
<br />public</span> ModelManager<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">)
<br />:</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br />{
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()
<br />{</span></b>
<br />
<br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br />{</span></b><span style="color: rgb(255, 0, 0);">
<br />for</span><b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(255, 102, 51);">int</span> i<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);">0</span><b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);"> <</span></b> models<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">; ++</span></b>i<b><span style="color: rgb(102, 51, 0);">){</span></b>
<br /> models<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">].</span></b>Update<b><span style="color: rgb(102, 51, 0);">();
<br />}</span></b>
<br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br />{</span></b>
<br />foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>model3d bm in models<b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> bm<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(((</span></b>Game1<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">).</span></b>camera<b><span style="color: rgb(102, 51, 0);">);
<br />}</span></b>
<br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()
<br />{</span></b>
<br />models<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> model3d<b><span style="color: rgb(102, 51, 0);">(</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Model<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"Colonial"</span><b><span style="color: rgb(102, 51, 0);">)));</span></b>
<br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>LoadContent<b><span style="color: rgb(102, 51, 0);">();
<br />}
<br />}
<br />}</span></b></pre>E' molto semplice come struttura, nella draw e nella update scorriamo tutti i modelli inseriti nella lista models del componente.... niente dipiù.
<br />Date un'occhiata a come viene aggiunto un modello alla lista nella LoadContent():
<br /><pre>models<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> model3d<b><span style="color: rgb(102, 51, 0);">(</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Model<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"Colonial"</span><b><span style="color: rgb(102, 51, 0);">)));
<br /></span></b></pre>Come vedete facciamo riferimento a "Colonial" che è il testo inserito nell'asset name del contenuto .x .
<br />
<br />La funzione Load è la solita chiamata che viene usata per inserire contenuti nella pipeline (in questo caso definiamo il template come "model"<model> ).
<br />
<br />
<br />L'ultimo step che manca è l'aggiunta dei componenti nel file game.cs.
<br />Copio solo la prima parte del file...il resto è immutato.
<br /><span style="font-weight: bold;">GAME1.cs</span>
<br /><pre><span style="color: rgb(153, 0, 0);"> public class</span> Game1<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Game<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b>
<br />GraphicsDeviceManager graphics<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br />SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span> Camera camera<b><span style="color: rgb(102, 51, 0);"> {</span></b> get<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"> protected</span> set<b><span style="color: rgb(102, 51, 0);">; }</span></b>
<br />ModelManager modelManager<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />public</span> Game1<b><span style="color: rgb(102, 51, 0);">()
<br />{</span></b>
<br /> graphics<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> GraphicsDeviceManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>RootDirectory<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Content"</span><b><span style="color: rgb(102, 51, 0);">;
<br />}</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()
<br />{</span></b>
<br /> camera<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Camera<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);">
<br /> new</span> Vector3<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">70</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);">60</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 40</span><b><span style="color: rgb(102, 51, 0);">),</span></b>
<br /> Vector3<b><span style="color: rgb(102, 51, 0);">.</span></b>Zero<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector3<b><span style="color: rgb(102, 51, 0);">.</span></b>Up<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>camera<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br /> modelManager<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> ModelManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>modelManager<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();
<br />}</span></b></pre>
<br />Aggiungiamo in poche parole le informazioni legate alla Camera e al ModelManager.
<br />
<br />Compilando da qui vedrete una bellissima Colonial One in 3d :P
<br />
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9gD8UkYSjXReyvFjheWQL8jtOn2MrpBGyiEQuBUIJrdPeg7XU26-8XOzJhXj8cJ1RHzynB5WaHHwunbPpd2Mx9WWegvgE3Cd2vxhBOQ2YDL_dqDeur_LOPpuB2U-eWoQbbudjAcu6b-s/s1600-h/colonial3.jpg"><img style="cursor: pointer; width: 400px; height: 313px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh9gD8UkYSjXReyvFjheWQL8jtOn2MrpBGyiEQuBUIJrdPeg7XU26-8XOzJhXj8cJ1RHzynB5WaHHwunbPpd2Mx9WWegvgE3Cd2vxhBOQ2YDL_dqDeur_LOPpuB2U-eWoQbbudjAcu6b-s/s400/colonial3.jpg" alt="" id="BLOGGER_PHOTO_ID_5329867922465658514" border="0" /></a>
<br />
<br /><span style="font-weight: bold;">Sorgenti:</span><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.2.zip"></a>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.3.zip">imparandoxna_3d.3.zip</a>
<br /><model>
<br /><span style="font-weight: bold;">Modello:</span>
<br /></model><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.3.modello.zip">imparandoxna_3d.3.modello..zip</a>
<br /><model>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /></model></model>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com3tag:blogger.com,1999:blog-1511468527759599388.post-49359172373267852602009-04-15T11:07:00.000-07:002011-10-05T00:45:28.666-07:003D.2) Xna tutorial 3d: Disegnare PrimitiveDopo il breve passaggio dello scorso post su alcuni concetti chiave del 3d, possiamo iniziare a scrivere qualcosa di concreto!
<br />
<br />Lo scopo di questo post sarà farvi capire come si disegna una superfice triangolare, il piano più semplice, tramite il quale possono essere composte tutte le altre forme e solidi, e come si eseguono alcune operazioni basilari su questa figura.
<br />
<br /><span style="font-weight: bold;">Anteprima Video:</span>
<br /><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/DVjDyKWV9Ag&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/DVjDyKWV9Ag&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object>
<br />
<br /><span style="font-weight: bold;">In ordine vedremo :</span>
<br />1) Creazione di una semplice camera fissa
<br />2) Disegnare un triangolo colorato utilizzando vertexPositionColor
<br />3) Effettuare operazioni di traslazione e rotazione sul triangolo creato
<br />
<br /><span style="font-weight: bold;">1) Crezione della camera</span> :
<br />Prima di tutto aggiungete una nuovo file di tipo GameComponent al progetto e chiamatelo Camera.cs.
<br />In primo luogo create due variabili di classe view e projection che identicicheranno le matrici di definizione della camera (fate un salto al pos precedente se non sapete di cosa sto parlando), e in seguito scrivete il costrutture in grado di accettare 4 parametri.
<br />Il game, la posizione della camera, il target, e il vettore Up.
<br />Poi molto semplicemente valoriziamo le matrici attraverso due funzioni messe a disposizione da XNA: <span style="font-weight: bold;">CreateLookAt</span> e <span style="font-weight: bold;">CreatePerspectiveView</span>, come potete notare queste funzioni prendono in ingresso i parametri dei quali abbiamo parlato nel post precedente ceh identificano proprio i valori necessari per le matrici view e projection.
<br />
<br /><span style="font-weight: bold;">CAMERA</span>----------------------------------------------------------------------
<br /><pre><span style="color:#0000ad;"> public</span> Matrix view<b><span style="color: rgb(102, 51, 0);"> {</span></b> get<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"> protected</span> set<b><span style="color: rgb(102, 51, 0);">; }</span></b><span style="color: rgb(153, 0, 0);">
<br /> public</span> Matrix projection<b><span style="color: rgb(102, 51, 0);"> {</span></b> get<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"> protected</span> set<b><span style="color: rgb(102, 51, 0);">; }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> Camera<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">,</span></b>Vector3 pos<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector3 target<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector3 up<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Inizializzo view
<br /></span></i> view<b><span style="color: rgb(102, 51, 0);"> =</span></b> Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>CreateLookAt<b><span style="color: rgb(102, 51, 0);">(</span></b>pos<b><span style="color: rgb(102, 51, 0);">,</span></b> target<b><span style="color: rgb(102, 51, 0);">,</span></b> up<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Inizializzo projection
<br /></span></i> projection<b><span style="color: rgb(102, 51, 0);"> =</span></b> Matrix<b><span style="color: rgb(102, 51, 0);">.</span></b>CreatePerspectiveFieldOfView<b><span style="color: rgb(102, 51, 0);">(</span></b>
<br /> MathHelper<b><span style="color: rgb(102, 51, 0);">.</span></b>PiOver4<b><span style="color: rgb(102, 51, 0);">,
<br /> (</span></b><span style="color: rgb(255, 102, 51);">float</span><b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Width<b><span style="color: rgb(102, 51, 0);"> /
<br /> (</span></b><span style="color: rgb(255, 102, 51);">float</span><b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Height<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);">
<br /> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 100</span><b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b></pre>Ora per fare in modo che la camera entri a far parte del nostro ciclo, aggiungiamo la variabile di classe
<br /><pre> Camera camera<b><span style="color: rgb(102, 51, 0);">;
<br />
<br /></span></b></pre>al file Game1.cs e al funzione initialize del file GAme.cs aggiungiamo:
<br /><pre><i><span style="color: rgb(153, 153, 153);"> //Creiamo la camera e la aggiungiamo ai componenti
<br /></span></i> camera<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Camera<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector3<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">0</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 5</span><b><span style="color: rgb(102, 51, 0);">),</span></b> Vector3<b><span style="color: rgb(102, 51, 0);">.</span></b>Zero<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector3<b><span style="color: rgb(102, 51, 0);">.</span></b>Up<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>camera<b><span style="color: rgb(102, 51, 0);">);</span></b></pre>
<br />A questo punto compilando dovreste vedere la solita schermata blu vuota di xna... ma la state visualizzando attraverso una camera :D
<br />
<br />Ora cerchiamo di dare alla camera qualcosa da visualizzare, altrimenti non c'è molto gusto.
<br />
<br /><span style="font-weight: bold;">2) Disegnare un triangolo colorato:</span>
<br />Per disegnare questo triangolo avremo bisogno prima di tutto di 3 punti nello spazio (vertici) e dei colori da associare a questi punti (xna pensarà automaticamente a come miscelare i colori).
<br />
<br />La variabile che definirà i nostri vertici è un array di tipo <span style="font-weight: bold;">VertexPositionColor</span>, che è un tipo di oggetto particolare in grado di ospitare inforamzioni di posizione e di colore appunto.
<br />
<br />Ora analizziamo il file game.cs dove avverranno tutte le logiche che ci permetteranno di disegnare il triangolo.
<br />
<br />Copio tutto il codice e velo spiego funzione per funzione.
<br /><span style="font-weight: bold;">GAME.CS</span>-----------------------------------------------------------
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Audio<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GamerServices<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Media<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Net<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Storage<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />namespace</span> imparandoxna_3d2<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><i><span style="color: rgb(153, 153, 153);">
<br /></span></i><span style="color: rgb(153, 0, 0);"> public class</span> Game1<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Game<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b>
<br /> GraphicsDeviceManager graphics<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br />
<br /><span style="font-weight: bold;"> Camera camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b> <span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[]</span></b><span style="font-weight: bold;"> vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> Game1<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> graphics<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> GraphicsDeviceManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>RootDirectory<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Content"</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /><span style="font-weight: bold;"> //Creiamo la camera e la aggiungiamo ai componenti</span> </span></i><span style="font-weight: bold;"> camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> Camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">this</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> Vector3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 5</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="font-weight: bold;"> Vector3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Zero</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> Vector3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Up</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b> <span style="font-weight: bold;"> Components</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Add</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Inizializiamo i vertici da disegnare
<br /></span></i>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /><i><span style="color: rgb(153, 153, 153);"> // Create a new SpriteBatch, which can be used to draw textures.
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br /><span style="font-weight: bold;"> vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">];</span></b> <span style="font-weight: bold;">
<br /> vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">] =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">new</span><span style="font-weight: bold;"> Vector3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="font-weight: bold;"> Color</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Blue</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);
<br /></span></b> <span style="font-weight: bold;"> vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">] =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">new</span><span style="font-weight: bold;"> Vector3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">, -</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="font-weight: bold;"> Color</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Red</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> <span style="font-weight: bold;">vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">2</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">] =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">new</span><span style="font-weight: bold;"> Vector3</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(-</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">, -</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="font-weight: bold;"> Color</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">White</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);"> <span style="font-weight: bold;"> // TODO: use this.Content to load your game content here</span>
<br /></span></i><b><span style="color: rgb(102, 51, 0);"> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // Allows the game to exit
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>GamePad<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">(</span></b>PlayerIndex<b><span style="color: rgb(102, 51, 0);">.</span></b>One<b><span style="color: rgb(102, 51, 0);">).</span></b>Buttons<b><span style="color: rgb(102, 51, 0);">.</span></b>Back<b><span style="color: rgb(102, 51, 0);"> ==</span></b> ButtonState<b><span style="color: rgb(102, 51, 0);">.</span></b>Pressed<b><span style="color: rgb(102, 51, 0);">)</span></b><span style="color: rgb(153, 0, 0);">
<br /> this</span><b><span style="color: rgb(102, 51, 0);">.</span></b>Exit<b><span style="color: rgb(102, 51, 0);">();</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // TODO: Add your update logic here
<br /></span></i>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b>
<br /><span style="color: rgb(153, 0, 0);">
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> GraphicsDevice<b><span style="color: rgb(102, 51, 0);">.</span></b>Clear<b><span style="color: rgb(102, 51, 0);">(</span></b>Color<b><span style="color: rgb(102, 51, 0);">.</span></b>CornflowerBlue<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /><span style="font-weight: bold;"> // inviamo la tipologia di dato da procesare al graphic device</span> </span></i><span style="font-weight: bold;">
<br /> GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">VertexDeclaration</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> VertexDeclaration</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">VertexElements</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><i style="font-weight: bold;"><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Disegniamo il triangolo
<br /></span></i><span style="font-weight: bold;"> BasicEffect effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> BasicEffect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> null</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b> <span style="font-weight: bold;">
<br /> effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">World</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> Matrix</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Identity</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;
<br /> </span></b> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">View</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">view</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;
<br /> </span></b> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Projection</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">projection</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;
<br /> </span></b> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">VertexColorEnabled</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><b style="font-weight: bold;"><span style="color: rgb(0, 0, 0);"> true</span></b><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Begin</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();</span></b> <span style="font-weight: bold;">
<br /> foreach</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> (</span></b><span style="font-weight: bold;">EffectPass pass in effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">CurrentTechnique</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Passes</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> <span style="font-weight: bold;">pass</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Begin</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();
<br /> </span></b> <span style="font-weight: bold;">GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">DrawUserPrimitives</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"><</span></b><span style="font-weight: bold;">VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">>(</span></b><span style="font-weight: bold;">PrimitiveType</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">TriangleStrip</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> ,</span></b><span style="font-weight: bold;">vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> <span style="font-weight: bold;">pass</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">End</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b> <span style="font-weight: bold;">
<br /> effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">End</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();</span></b>
<br />
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br />}
<br />}
<br />
<br /></span></b></pre>Abbiamo aggiunto prima di tutto la variabile di classe
<br /><pre><span style="font-weight: bold;">VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">[]</span></b><span style="font-weight: bold;"> vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /></span></pre> che inizializziamo nella <span style="font-weight: bold;">loadContent</span>, definendo semplicemente che si tratta di un array di 3 elementi e ogni elemento avrà una posizione e un colore. Questi saranno quindi i vertici del nostro triangolo in posizioni e colori differenti.
<br />
<br />Ora la parte più laboriosa, la funzione <span style="font-weight: bold;">Draw</span>:
<br />In primo luogo guardiamo questa riga
<br /><pre><i><span style="color: rgb(153, 153, 153);"><span style="font-weight: bold;"> // inviamo la tipologia di dato da procesare al graphic device</span> </span></i><span style="font-weight: bold;">
<br /> GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">VertexDeclaration</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> VertexDeclaration</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">VertexElements</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><i style="font-weight: bold;"><span style="color: rgb(153, 153, 153);">
<br /></span></i></pre> Quello che stiamo facendo qui è avvisare il GraphichsDevice che stiamo per passare un determinato tipo di Vertici, quindi Xna avvierà delle logiche (che non conosco) che saranno in grado di gestire questo tipo di dato!
<br />
<br />Prima di spiegarvi l'ultimo blocco sono obbligato ad i ntrodurvi prevente il sistema tramite il quale xna disegna il 3D.
<br />Qualcuno di voi avrà sentito già parlare di vertex e pixel shader immagino...questi due tipi di "funzioni" sono stati introdotti da pochi anni in quella che è la logica della pipeline grafica, permettendo di scaricare la cpu da compiti e calcoli che possono essere demandati alla GPU.
<br />Operazioni che consentono di creare tutti quei bellissimi effetti che trovate nei giochi di ultima generazione (blur, glow riflessi etc) liberando la CPU dall'onerosa quantità di calcoli altrimenti necessari e spostando il tutto lato video.
<br />
<br />Questo tipo di operazioni vengono gestite in DirectX (e quindi in XNA) tramite un liguaggio chiamato HLSL (High Level Shader Language), e XNA utilizza sempre questo passaggio nel suo processo di rendering del 3d.
<br />Non preoccupatevi! potrete continuare questo tutorial senza sapere assolutamene scrivere una riga di HLSL, dato che xna fornisce una classe chiamata appunto BasicEffect, che si occuperà di gestire i nostri 3d attraverso un semplice e predefinito HLSL.
<br />
<br />Dato che farò un post dedicato interamente a HLSL, per ora non mi dilungo e chiudo dicendovi che è possibile passare dati direttamente da XNA agli effetti che creiamo e che ogni effetto è composto da una o più Techiche e ogni tecnica da uno o più passi.... quando vedremo un file HLSL capirete meglio, per ora fidatevi :P e guardate come procediamo per stampare il nostro tanto atteso triangolo.
<br />
<br /><pre><i style="font-weight: bold;"><span style="color: rgb(153, 153, 153);"> //Disegniamo il triangolo
<br /></span></i><span style="font-weight: bold;"> BasicEffect effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> BasicEffect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> null</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b> <span style="font-weight: bold;">
<br /> effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">World</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> Matrix</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Identity</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;
<br /> </span></b> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">View</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">view</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;
<br /> </span></b> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Projection</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> camera</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">projection</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;
<br /> </span></b> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">VertexColorEnabled</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><b style="font-weight: bold;"><span style="color: rgb(0, 0, 0);"> true</span></b><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> <span style="font-weight: bold;">effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Begin</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();</span></b> <span style="font-weight: bold;">
<br /> foreach</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> (</span></b><span style="font-weight: bold;">EffectPass pass in effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">CurrentTechnique</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Passes</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> <span style="font-weight: bold;">pass</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Begin</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();
<br /> </span></b> <span style="font-weight: bold;">GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">DrawUserPrimitives</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"><</span></b><span style="font-weight: bold;">VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">>(</span></b><span style="font-weight: bold;">PrimitiveType</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">TriangleStrip</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> ,</span></b><span style="font-weight: bold;">vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> <span style="font-weight: bold;">pass</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">End</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b> <span style="font-weight: bold;">
<br /> effect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">End</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">();</span></b><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"></span></b></pre> Prima di tutto definiamo l'effetto base del quale vi stavo parlando, poi passiamo a questo effetto informazioni di posizione proiezione della camera attraverso i parametri View e Projection e di posizione del triangolo stesso attraverso la matrice World.
<br />In questo caso passiamo al parametro World il valore MatrixIdentity che identifica un parametro "nuetro" (un pò come lo zero nelle somme e l'1 nelle moltiplicazioni) questo farà si che il triangolo venga disegnato a coordinate (0,0,0).
<br />
<br />Dopo aver abilitato la gestione dei colori, apriamo una sessione di elaborazione dell'effetto, racchiusa tra le funzioni Begin e End (un pò come succedete per quando lavoriamo con lo spriteBatch). Come vedete scorriamo ogni passo della tecnica attualmente utilizzata ( l'effetto base ha già una tecnica di deafault presettata), e per ogni passo ci curiamo di disegnare tramite la funzione :
<br /><pre><span style="font-weight: bold;"> GraphicsDevice</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">DrawUserPrimitives</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"><</span></b><span style="font-weight: bold;">VertexPositionColor</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">>(</span></b><span style="font-weight: bold;">PrimitiveType</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">TriangleStrip</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> ,</span></b><span style="font-weight: bold;">vertici</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);">1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);<span style="font-family:Georgia,serif;">
<br />
<br /></span></span></b></pre> I parametri passatti a questa funzioni indicano il metodo di congiunzione delle linee che uniscono i vertici disegnati (primitivetype.trianglestrip), la lista dalla quale prendere i punti da disegnare (vertici), un eventuale offset dal quale partire in questa lista (in questo caso 0) e infine il numero di figure che disegneremo (1).
<br />
<br />
<br />Compilando otterrete questo:
<br />
<br /><pre><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSR89ueaVkCz7kIWPNaZSq9vFPEWGuX6IYESX47TKJ7ruG6z_6k7Uqen9YW-gjTingtNHBegU-tXP4QG6XIa_-TbVkKwQnOOmy-ySRiT5nFGkMHQjfsAdt7d0d8faMTAamf70FtZ3Xk_8/s1600-h/triangolo1.jpg"><img style="cursor: pointer; width: 400px; height: 314px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhSR89ueaVkCz7kIWPNaZSq9vFPEWGuX6IYESX47TKJ7ruG6z_6k7Uqen9YW-gjTingtNHBegU-tXP4QG6XIa_-TbVkKwQnOOmy-ySRiT5nFGkMHQjfsAdt7d0d8faMTAamf70FtZ3Xk_8/s400/triangolo1.jpg" alt="" id="BLOGGER_PHOTO_ID_5325412348064492274" border="0" /></a></pre> e aggiungerei un bel "WOOOW!".....
<br />
<br />
<br /><span style="font-weight: bold;">3) Traslazione e rotazione del triangolo</span>
<br />Il terzo obiettivo che ci siamo posti è di dar vita a qualche animazione.
<br />Facciamo effettuare una semplice rotazione al triangolo, come prima cosa ricordate che la matrice sulla quale dobbiamo lavorare è la World perchè la nostra camerà non si sposterà.
<br />
<br />Andate nel file game1.cs aggiugnete la variabile di classe
<br /><pre><span style="font-weight: bold;">Matrix world</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> Matrix</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Identity</span><b><span style="color: rgb(102, 51, 0);"><span style="font-weight: bold;">;</span>
<br /></span></b></pre>E nella funzione Draw()
<br />dove inizializziamo la variabile effect.world
<br />scrivete
<br /><pre style="font-weight: bold;">effect<span style="color: rgb(102, 51, 0);">.</span>World<span style="color: rgb(102, 51, 0);"> =</span> world<span style="color: rgb(102, 51, 0);">;</span></pre>A questo punto siamo in grado di modificare il valore della matrice world nella funzione update
<br />aggiungete:
<br /><pre style="font-weight: bold;">world<span style="color: rgb(102, 51, 0);"> *=</span> Matrix<span style="color: rgb(102, 51, 0);">.</span>CreateRotationY<span style="color: rgb(102, 51, 0);">(</span>MathHelper<span style="color: rgb(102, 51, 0);">.</span>PiOver4<span style="color: rgb(102, 51, 0);"> /</span><span style="color: rgb(153, 153, 0);"> 20</span><span style="color: rgb(102, 51, 0);">) ;</span></pre>e compilando vedremo il nostro triangolo ruotare.....anche se a un certo punto<span style="font-weight: bold;"> lo vedrete sparire </span>, proprio quando dovrebbe mostrarci la sua faccia posteriore.
<br />
<br />Questo succede perchè di default viene attivata una funzione che nasconde le facce chiamate Backface ovvero le face che sono orientate in verso opposto alla normale del piano. Questo serve per risparmiare di mostrare e calcolare aree normalmente non visibili. Se immaginate un cubo composto da 6 facce, noi vediamo normalmente solo il lato esterno... quindi non avrebbe senso disegnare anceh il lato interno del cubo.
<br />Per attivare questa modalità di visualizzazione aggiungiamo dopo il metodo clear nella draw:
<br /><pre style="font-weight: bold;">GraphicsDevice<span style="color: rgb(102, 51, 0);">.</span>RenderState<span style="color: rgb(102, 51, 0);">.</span>CullMode<span style="color: rgb(102, 51, 0);"> =</span> CullMode<span style="color: rgb(102, 51, 0);">.</span>None<span style="color: rgb(102, 51, 0);">;</span></pre>Ricompilando ora vedrete anche il lato posteriore :D
<br />
<br />Bene per oggi direi che di concetti ne abbiamo visti un bel pò!
<br />come al solito allego il codice sorgente del progetto.
<br />
<br /><span style="font-weight: bold;">Codice Sorgente:</span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/imparandoxna_3d.2.zip">imparandoxna_3d.2.zip</a>
<br />
<br />Alla prossima!Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com6tag:blogger.com,1999:blog-1511468527759599388.post-32602510142991047352009-04-14T13:05:00.000-07:002009-04-16T13:49:08.467-07:003d.1) Xna tutorial 3d: IntroduzioneRieccomi dopo un paio di settimane di silenzio, torno con piacere a raccontarvi qualcosa di (spero) interessante su XNA.<br /><br /><span style="font-weight: bold;">Video Anteprima:</span><br /><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/7tNlq-sqm48&hl=it&fs=1&color1=0x234900&color2=0x4e9e00"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/7tNlq-sqm48&hl=it&fs=1&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object><br /><br />Con l'ultimo post avevo chiuso una breve guida sullo sviluppo di un semplice videogame in 2d, chi ha seguito la guida ha potuto notare non si trattava di un videogame poi così semplice da strutturare!!<br />Con il post di questa sera introdurrò l'argomento che forse vi interessa di più ... <span style="font-weight: bold;">il 3D in Xna</span>. Evito premesse troppo lunghe che tanto non interessano a nessuno e passo al sodo!<br /><br /><span style="font-weight: bold;">3D XNA</span><br />Fino ad ora abbiamo trattato grafica in due dimensioni X e Y, dove disegnare un oggetto sullo schermo è molto simile a posizionare un elemento su una lavagna, naturalmente possiamo limitarci solo a definire 2 coordinate spaziali. Nell'ambito 3d, come è facile immaginare, andremo ad aggiungere l'informazione di profondità della scena:<br />Il sistema di coordinate 3d aggiunge l'elemento Z = profondità, mentre per quanto riguarda le coordinate X e Y il discorso rimane invariato X = Posizione orizzontale Y = Posizione Verticale.<a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsnVbPygb8tEqz3GcWXMqHQ2sd4LWbN8X8uglkl42q6tjoBlLcT_vL85t7K-fnkh8yYLKbA9galjWmARIXj-TvgoR7bwEQxpKBFrw8e7Fr8aeu3Br7OXQ7cLgOILi0YmbpRHe_V9ridRc/s1600-h/coordSystem.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 238px; height: 280px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsnVbPygb8tEqz3GcWXMqHQ2sd4LWbN8X8uglkl42q6tjoBlLcT_vL85t7K-fnkh8yYLKbA9galjWmARIXj-TvgoR7bwEQxpKBFrw8e7Fr8aeu3Br7OXQ7cLgOILi0YmbpRHe_V9ridRc/s400/coordSystem.jpg" alt="" id="BLOGGER_PHOTO_ID_5324645914587860610" border="0" /></a><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRuLveiPF2tqp2T1umc7GZNWVjIv-qCii1Nx0_dG8APpzfYDNhBX_Xxl11uX5ON0V3b3ayWi4RQKhDKIptqegUCYOK45j3y-IVqCODuY9W5KceWIZ7yqpciKemYorM06DoRmnkHeONxv8/s1600-h/sout-f04.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 197px; height: 178px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjRuLveiPF2tqp2T1umc7GZNWVjIv-qCii1Nx0_dG8APpzfYDNhBX_Xxl11uX5ON0V3b3ayWi4RQKhDKIptqegUCYOK45j3y-IVqCODuY9W5KceWIZ7yqpciKemYorM06DoRmnkHeONxv8/s400/sout-f04.jpg" alt="" id="BLOGGER_PHOTO_ID_5324656590429982994" border="0" /></a><br />Un piccolo appunto sulla profondità:<br />Il sistema di coordinate utilizzato in XNA si chiama "<span style="font-weight: bold;">Right Handed Coordinate System</span>" e indica che il valore profondità aumenta procedendo nella direzione che ipoteticamente andrebbe dal monitor -> verso voi e diminuisce nella direzione opposta.<br /><br />Per capire perchè questo tipo di sistema è chiamato right handed seguite queste regole :<br />1) rivolgete il palmo della mano destra verso di voi e aprite la mano<br />2) immaginate che il vostro pollice sia l'asse delle X<br />3) immaginate che il vostro indice sia l'asse delle Y<br />4) ora piegate il medio verso di voi ... questo sarà l'asse delle Z ... che viene appunto "verso di voi"<br /><br />Se provate a fare la stessa cosa con la mano sinistra, partendo dal punto due, vedrete che per avere il pollice associato alle X e l'indice alle Y dovrete girare il palmo verso il monitor e così anche il medio... in questo caso stiamo utilizzando un "<span style="font-weight: bold;">Left Handed Coordinate System</span>"... dove l'asse Z aumenta di valore andando "dentro al monitor" e diminuisce "uscendo verso di voi".<br /><br /><span style="font-weight: bold;">Le Matrici:</span><br />Sono una nozione fondamentale per tutto quello che riguarda la matematica 3d, si tratta di un ragruppamento di valori per righe e colonne e rappresentano uno strumento importantissimo in quanto sono indispensabili per effettuare operazioni come trasformazioni, rotazioni e ridimensionamenti di oggetti nello spazio, ottimizzando il numero di operazioni necessarrie per effettuare questi calcoli (vedi moltiplicazione di matrici) .<br />Questo argomento andrebbe trattato con molta cura per essere pienamente comprensibile e non è questo il posto giusto per avere tutte queste info ... vi rimando a un veloce studio qui<br /><br /><span style="font-weight: bold;">La parola di wikipedia:</span><br /><a href="http://it.wikipedia.org/wiki/Matrice">http://it.wikipedia.org/wiki/Matrice</a><br /><br /><span style="font-weight: bold;">Un tutorial in italiano... con molte immagini</span>:<br /><a href="http://www.clickitaliansoftware.net/hosted/vgcgroup/Tutorials/TutorialZip/TutoMatrici/index.htm#A24">http://www.clickitaliansoftware.net/hosted/vgcgroup/Tutorials/TutorialZip/TutoMatrici/index.htm#A24</a><br /><br /><span style="font-weight: bold;">L'approfondimento del tutorial sopra riferimento a trasfromazioni/rotazioni/ridimensionanti</span>:<br /><a href="http://www.clickitaliansoftware.net/hosted/vgcgroup/Tutorials/TutorialZip/TutoTrasformazioni/index.htm#A34">http://www.clickitaliansoftware.net/hosted/vgcgroup/Tutorials/TutorialZip/TutoTrasformazioni/index.htm#A34</a><br /><br />Spero di riuscire a scrivere un tutorial su questo argomento prendendo spunto da un <a href="http://www.jbpub.com/catalog/9781598220162/">ottimo libro</a> che ho utilizzato per directX che trattava le basi della matematica 3d in modo molto semplice.<br /><br />Dopo questa poco utile presentazione delle matrici vi tiro un pò su di morale dicendovi che XNA ha delle ottime funzioni che ci aiuteranno nell'utilizzo delle matrici senza doversi addentrare più di tanto in questo argomento e che esiste proprio una classe chiamata Matrix che ha tutto quello che serve.<br /><br /><br /><span style="font-weight: bold;">Le Camere:</span><br />Un altro elemento che differenzia il 2d dal 3d è come viene interpretata la posizione di un elemento.<br />Se ipotizzassimo di avere un oggetto in X = 0, Y= 0, Z = 0 (quindi sull'origine degli assi) verrebbe spontaneo pensare che l'oggetto venga visualizzato al centro del nostro monitor. In realtà, per determinare dove l'oggetto verrà visualizzato, subentra un secondo fattore... <span style="font-weight: bold;">la Camera.<span style="font-weight: bold;"><span style="font-weight: bold;"><br /></span></span></span>La camera è l'elemento attraverso il quale viene definito il punto di vista dal quale osserviamo la scena ed è caratterizata principalmente da una posizione e da un orientamento...immaginate una stanza e voi con in mano una qualsiasi telecamera, la camerà sarà posizionata in qualche parte dello spazio e avrà una direzione verso la quale è rivolto l'obbiettivo.<br /><div style="text-align: left;"><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsnVbPygb8tEqz3GcWXMqHQ2sd4LWbN8X8uglkl42q6tjoBlLcT_vL85t7K-fnkh8yYLKbA9galjWmARIXj-TvgoR7bwEQxpKBFrw8e7Fr8aeu3Br7OXQ7cLgOILi0YmbpRHe_V9ridRc/s1600-h/coordSystem.jpg"><img style="margin: 0px auto 10px; display: block; text-align: center; cursor: pointer; width: 183px; height: 215px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgsnVbPygb8tEqz3GcWXMqHQ2sd4LWbN8X8uglkl42q6tjoBlLcT_vL85t7K-fnkh8yYLKbA9galjWmARIXj-TvgoR7bwEQxpKBFrw8e7Fr8aeu3Br7OXQ7cLgOILi0YmbpRHe_V9ridRc/s400/coordSystem.jpg" alt="" id="BLOGGER_PHOTO_ID_5324645914587860610" border="0" /></a>Utilizzando l'immagine sopra immaginate che la nostra camera sia il punto azzurro (coordinate possibili : X= 10 Z = 10 Y = 10) se l'obbiettivo (target) fosse in 0,0,0 voi vedresta l'0ggetto posizionato sull'intersezione degli assi, al centro del monitor. Cambiando la posizione del target questo si sposterebbe dalla posizione centrale. Mentre muovendo la camera, l'oggetto rimarrebbe sempre al centro del vostro schermo dato che l'obbiettivo risiede proprio sull'oggetto.<br />Oltre a informazioni di posizione possiamo naturalmente far ruotare la nostra camera, il che farà inesorabilmente modificare la visualizzazione del nostro oggetto.<br /><br />Guardate la "video anteprima" a inizio post per capire meglio quello che sto cercando di spiegarvi :<br />Abbiamo, tanto per cambiare, un'astronave (Viper Mk II) presa da Battlestar Galactica (modello da <a href="http://sketchup.google.com/3dwarehouse/details?mid=bf9f0624e2002b3d339bd6b570381585">warehouse di sketchup</a> e trasformato in un formato leggibile dalla Pipeline di XNA tramite un <a href="http://www.3drad.com/Google-SketchUp-To-DirectX-XNA-Exporter-Plug-in.htm">apposito tool</a> ). Come potete vedere la camera ruota intorno all'oggetto e su se stessa. Il risultato è una diversa visualizzazione dell'astronave.<br /><br />Da queste righe capiamo dunque che per definire una camera nello spazio sono necessari 3 parametri:<br /><span style="font-weight: bold;">1) Posizione della camera</span><br /><span style="font-weight: bold;">2) Posizione del Target</span><br /><span style="font-weight: bold;">3) Verso superiore della camera: </span>un vettore che indica quale direzione è il lato "sopra" della camera. In assenza di rotazioni questo lato sarebbe X= 0, Y= 1, Z= 0 (vedremo meglio questo elemento nel tutorial dedicato alla creazione di una camera tra qualche post).<br /><br />Ora per conoscere e capire altri concetti legati alle camere guardate questa immagine (Fonte: wikipedia http://en.wikipedia.org/wiki/Viewing_frustum).<br /><br /><div style="text-align: center;"><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjinpbPOU2lSL0oXeROx3kfIbOouEaYAkwQK7HCbi9SwxDThdWVAI-BO1Hj2288sf4I543p8J7sdg2XOJDdC6HIHXJMUSDlSuk-rhwb60HXKVvX0a7RLq3EjcNqWFkvwgSoWSxwySnh-E/s1600-h/ViewFrustum_01.png"><img style="cursor: pointer; width: 344px; height: 344px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhjinpbPOU2lSL0oXeROx3kfIbOouEaYAkwQK7HCbi9SwxDThdWVAI-BO1Hj2288sf4I543p8J7sdg2XOJDdC6HIHXJMUSDlSuk-rhwb60HXKVvX0a7RLq3EjcNqWFkvwgSoWSxwySnh-E/s400/ViewFrustum_01.png" alt="" id="BLOGGER_PHOTO_ID_5324656367585969890" border="0" /></a><br /><br /><br /><br /></div>Questa immagine rappresenta quello che viene chiamato <span style="font-weight: bold;">Viewing Frustum</span>, ed è essenzialmente un metodo per rappresentare quello che effettivamente viene colto dalla camera, per farla brevissima, se un oggetto si trova all'interno del solido evidenziato, l'oggetto sarà visibile nella scena.<br />Per definire questo solido occorrono 4 parametri che tecnicamente si chiamano :<br /><span style="font-weight: bold;">1) Field of view:</span> l'angolo di visualizzazione (ampiezza dei tratti che escono dalla camera)<br /><span style="font-weight: bold;">2) Aspect Ratio:</span> le proporzioni di visualizzazione (per esempio 800X600...1024X768....16:9)<br /><span style="font-weight: bold;">3) Near plane:</span> la distanza del primo pannello del solido (che indica quando un oggetto può essere vicino alla camera senza essere visualizzato e da dove inizierà la visualizzazione)<br /><span style="font-weight: bold;">4) Far Plane </span>: Il piano posto di fronte al near plane che indica la fine del solido di visualizzazione... la base della piramide tronca chiamata Viewing Frustum.<br /><br /><br /><span style="font-weight: bold;">Matrici World, View e Projection:</span><br />Abbiamo ipotizzato di avere un oggetto al centro del nostro sistema di coordinate, per definire in che modo l'oggetto viene posizionato nel sistema viene utilizzata una matrice chiamata <span style="font-weight: bold;">World</span>.<br />Lo scopo di questa matrice è di definire il posizionamento dell'oggetto nello spazio identificando dunque anche rotazioni e ridimensionamenti.<br />La matrice View e la matrice projection vengono invece utilizzate per definire la camera. PEr quanto riguarda la matrice <span style="font-weight: bold;">View</span> viene creata utilizzando un particolare metodo di XNA (CreatePerspectiveFieldOfView) che prende in ingresso 3 parametri:<br />Posizione della camera, Posizione del target e vettore Up ... che guardacaso sono proprio i parametri che abbiamo definito qualche riga sopra.<br />La matrice <span style="font-weight: bold;">Projection</span> invece indica come viene creata la proiezione di quanto catturato dalla camera e come presentare a monitor questa proiezione.<br />La funzione associata a questa matrice è la CreatePerspectiveFieldOfView e prende come parametri gli altri 4 che vi ho presentato sopra parlandovi del frustum (field of view, aspect ratio, near plane, far plane).<br /><br />Per quanto riguarda la teoria vi ho mostrato a grandi linee tutto quello che serve per poter seguire i prossimi tutorial. Nel prossimo post inizieremo a scrivere il primo codice per disegnare quelle che vengono chiamate "primitive" e vedremo all'azione una camera.<br /><br />A prestissimo!Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com2tag:blogger.com,1999:blog-1511468527759599388.post-21736290735560337372009-03-23T14:16:00.000-07:002011-10-05T00:46:10.130-07:009) Xna Videogame Tutorial: Gestione delle scene e menuBentornati!!! Quello di questa sera sarà l'ultimo articolo attraverso il quale chiuderemo lo sviluppo del nostro primo videogame in 2d.
<br />Sarà anche la lezione più complessa e corposa, proprio per questo motivo non potrò copiare l'intero codice come ho fatto nelle precedenti lezioni, ma serete comunque in grado di seguirmi, dato che prenderò in esame i punti più complessi e cercherò di presentarvi a priori la situazione che andremo a ricreare.
<br /><span>Vi faccio subito notare che tutto quello che avete prodotto fino ad ora non viene buttato via... semplicemente preferisco partire dal progetto già completo per aiutarmi nella spiegazione e darvi gli ultimi concetti per mettere insieme un gioco semplice ma almeno abbastanza completo! Molto di quello che avete scritto nelle lezioni precedenti lo ritroverete qui tale e quale e tutti i concetti appresi sono assolutamente necessari per proseguire e comprendere la lezione qui sotto :D</span>
<br />
<br /><span style="font-weight: bold;">Anteprima Video (senza audio):</span>
<br /><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/i0TNC6yiDSU&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/i0TNC6yiDSU&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>
<br />
<br />Quello che cercherò di spiegarvi questa sera è come utilizzare i GameComponents per ottenere dei piccoli micromoduli "autonomi" e riutilizzabili. Attraverso questi elementi creeremo una logica di <span style="font-weight: bold;">navigazione delle scene,</span><span> che vi permetterà di avere una schermata di menu, la scena dove si svolge il gameplay e una schermata di Vittoria- fine partita (in più lascerò una scena libera da utilizzare come meglio credete...).
<br />Nella creazione di queste scene gestiremo anche l'audio! Non vi spiegherò l'utilizzo di XACT in questa lezione (prometto che lo farò più avanti) ma vi darò già i file prodotti da questo ottimo tool per poter essere direttamente utilizzati nel nostro videogame.
<br />Ok...andiamo per gradi, prima di tutto scaricate il file zip contenente i codici... aprite il progetto e seguitemi :D
<br /></span><span style="font-weight: bold;">
<br />CODICE SORGENTE: </span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/6.2dgame.zip">6.2dgame.zip</a>
<br />
<br /><span>Come vedrete ho diviso i contenuti in cartelle, ecco qui uno screen della situazione:
<br />
<br />
<br /></span><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt8xMYN1sWPUaDbGzbeGopNCRQrHzW2MtKBxQ1mDN8aLJUSdDuad5it_vtbGlNZxibcnDByVj8xJEaALGs5AeGk0VMSdk8yMbq3qXrv2QwS_ucrfDyjwObPHwb9afXrHe9D3L9XZmDo4g/s1600-h/contenuti.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgt8xMYN1sWPUaDbGzbeGopNCRQrHzW2MtKBxQ1mDN8aLJUSdDuad5it_vtbGlNZxibcnDByVj8xJEaALGs5AeGk0VMSdk8yMbq3qXrv2QwS_ucrfDyjwObPHwb9afXrHe9D3L9XZmDo4g/s400/contenuti.jpg" alt="" id="BLOGGER_PHOTO_ID_5316502739423373922" border="0" /></a>Rispetto al solito vedete molti più file, molti dei quali sono i famosi "micromoduli" dei quali vi parlavo sopra.
<br />Non vi preoccupate perchè li analizzeremo tutti e vedrete che non saranno assolutamente complicati da comprendere.
<br />Un piccolo appunto su quest'ultima lezione:
<br />Tutte le cose che vi spiegherò riguardanti la gestione delle scene e i menu le ho imparate dal libro <span style="font-weight: bold;">"Beginning XNA 2.0 Game Programming: From Novice to Professional" </span>, Ho seguito solo la prima parte dato che quando è iniziata la parte 3d ho preferito passare a <span style="font-weight: bold;">learning xna 3.0</span> visto che l'ho trovato molto più semplice da seguire.
<br />
<br />Facciamo una carrellata veloce sulle cartelle che compongono il progetto:
<br />Nella cartella <span style="font-weight: bold;">Core</span> sono presenti i file centrali, dei quali ci serviremo per creare oggetti specifici. Tra questi conoscete già lo SpriteManager, mentre per quanto riguarda gli altri file li analizzeremo uno ad uno in seguito.
<br />Nella cartella <span style="font-weight: bold;">Sprite</span> ritrovate semplicemente i tipi di sprite che avete visto nelle lezioni precedenti, quindi la classe astratta Sprite e le classi per gestire sprite controllabili dall'utente e sprite automatizzati.
<br />
<br />Nella cartella <span style="font-weight: bold;">Scene </span>infine, trovate tutte le scene che comporranno la nostra navigazione durante il ciclo di vita del programma.
<br />
<br />E' proprio da qui che partirei introducendovi la logica di game scene che ho utilizzato:
<br />
<br /><span style="font-weight: bold;">Le Scene</span> <span style="font-weight: bold;">di Gioco</span>
<br />Una scena di gioco non è altro che un'insieme di componenti e di informazioni utili in un determinato punto del programma. Per comprendere meglio quello che intendo dire, prendiamo come esempio un menu e il gioco che avete creato fino alla scorsa lezione. Parliamo dunque di due momenti del programma sconnessi tra di loro, la scena iniziale si occuperà di presentarvi il menu di gioco attraverso il quale potrete decidere di iniziare la partita o di visualizzare una schermata di help. La scena del gameplay invece, rappresenta il gioco vero e proprio, quindi esclude tutte le parti legate al menu e mostra unicamente gli elementi che compongono il gameplay.
<br />
<br />Per quanto riguarda il nostro video game, produrremo le scene presentate in questa immagine:
<br />
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKhRaKYR706WBLLStppKPIeuxaTdgO0kUEIA5O1GvaxkbKYzFFHdCkqA9b_HMiGA9ZGVbh9wVRUqRiHJ6CS-ExsNTWP9uRYo39ztEX6wIuijKnF5k9RWuW4Tw2Kdwm797sogfz8lWSVWA/s1600-h/scene.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 338px; height: 400px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjKhRaKYR706WBLLStppKPIeuxaTdgO0kUEIA5O1GvaxkbKYzFFHdCkqA9b_HMiGA9ZGVbh9wVRUqRiHJ6CS-ExsNTWP9uRYo39ztEX6wIuijKnF5k9RWuW4Tw2Kdwm797sogfz8lWSVWA/s400/scene.jpg" alt="" id="BLOGGER_PHOTO_ID_5316510720553514642" border="0" /></a>
<br />
<br />
<br />
<br />
<br /><span>
<br />
<br />
<br /></span>
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br />
<br /><span style="font-weight: bold;">StartScene:</span>
<br />Dove viene presentato il menu
<br />
<br /><span style="font-weight: bold;">PlayScene:</span>
<br />Il gioco
<br />
<br /><span style="font-weight: bold;">HelpScene:</span>
<br />Dove poter mostrare un'immagine di help
<br />
<br /><span style="font-weight: bold;">WinScene:</span>
<br />Schermata presentata dopo che dalla PlayScene si raggiunge un determinato punteggio
<br />
<br />Avrei potuto aggiungere anche una endGameScene ma a livello dimostrativo sarebbe stato identico che creare la WinScene ... quindi non sarebbe stato molto utile per voi.
<br />
<br />Ora che sappiamo cosa andremo a creare analizzerei la classe <span style="font-weight: bold;">GameScene</span> presente nella cartella Core, dato che utilizzeremo proprio questa classe come padre delle scene sopra descritte. Come vi dicevo non copierò tutti i codici, ma solo le parti fondamentali.... quindi aprite il file GameScene.cs e seguitemi da li.
<br />
<br /><span style="font-weight: bold;">GAMESCENE-------------------------------------------------------------------------------</span>
<br />
<br />Ogni scena avrà lo scopo di contenere uno o più componenti che a loro volta avranno determinati compiti.
<br />La prima cosa che serve alla classe gamescene è dunque un contenitore lista per i vari componenti.
<br /><pre> components<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> List<b><span style="color: rgb(102, 51, 0);"><</span></b>GameComponent<b><span style="color: rgb(102, 51, 0);">>();
<br /></span></b></pre>Un secondo elemento da analizzare è la presenza delle voci <span style="font-weight: bold;">Visible</span> e <span style="font-weight: bold;">Enabled </span>, questi sono due booleani utilizzati per far si che un componente venga mostrato e attivato, in poche parole se un componente non è visibile (Visibile=false) non viene preso in considerazione nella funzione Draw mentre se non è attivo (enabled=false) non viene considerato nell'Update.
<br /><pre><i><span style="color: rgb(153, 153, 153);"> //Di default una scena non è visibile e non è attiva
<br /></span></i> Visible<b><span style="color: rgb(102, 51, 0);"> =</span></b><b><span style="color: rgb(0, 0, 0);"> false</span></b><b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Enabled<b><span style="color: rgb(102, 51, 0);"> =</span></b><b><span style="color: rgb(0, 0, 0);"> false</span></b><b><span style="color: rgb(102, 51, 0);">;</span></b></pre>Per quanto riguarda le due funzioni del gameloop vediamo il corpo centrale della update
<br /><pre><i><span style="color: rgb(153, 153, 153);"> // Update the child GameComponents
<br /></span></i><span style="color: rgb(255, 0, 0);"> for</span><b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(255, 102, 51);">int</span> i<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);"> <</span></b> components<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);">++)
<br /> {</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>components<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">].</span></b>Enabled<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> components<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">].</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br /> }</span></b></pre> Dove in poche parole scorriamo tutti i componenti della classe e se sono abilitati li aggiorniamo
<br />e la draw:
<br />
<br /><pre><i><span style="color: rgb(153, 153, 153);"> // Draw the child GameComponents (if drawable)
<br /></span></i><span style="color: rgb(255, 0, 0);"> for</span><b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(255, 102, 51);">int</span> i<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);"> <</span></b> components<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);">++)
<br /> {</span></b>
<br /> GameComponent gc<b><span style="color: rgb(102, 51, 0);"> =</span></b> components<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">];</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> ((</span></b>gc is DrawableGameComponent<b><span style="color: rgb(102, 51, 0);">) &&
<br /> ((</span></b>DrawableGameComponent<b><span style="color: rgb(102, 51, 0);">)</span></b>gc<b><span style="color: rgb(102, 51, 0);">).</span></b>Visible<b><span style="color: rgb(102, 51, 0);">)
<br /> {
<br /> ((</span></b>DrawableGameComponent<b><span style="color: rgb(102, 51, 0);">)</span></b>gc<b><span style="color: rgb(102, 51, 0);">).</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br /> }</span></b></pre>Dove renderizziamo i componenti della classe ( se sono di tipo drawable components naturalmente)
<br />Questi sono i punti centrali della classe astratta GameScene.
<br />A questo punto è necessario capire quali sono i componenti che dovranno formare le nostre scene,
<br />Analizziamoli uno ad uno prima di entrare nelle altre scene....
<br />
<br />Partiamo dal più semplice:
<br />
<br /><span style="font-weight: bold;">IMAGE COMPONENT:</span>...............................................................
<br />Componente utilizzato per la gestione delle immagini, è un componente molto semplice l'unica cosa da notare è il fatto che può stretchare un'immagine oppure posizionarla al centro dello schermo in base al parametro drawmode, vi basterà guardare il metodo draw di questo componente per capire come differenzia la scelta tra stretch e centered.
<br />
<br />Una cosa che mi preme farvi notare è invece l'utilizzo dei Servizi! guardate come viene valorizzato lo spriteBatch
<br /><pre>spriteBatch<b><span style="color: rgb(102, 51, 0);"> = (</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Services</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">GetService</span><b><span style="color: rgb(102, 51, 0);">(</span></b>typeof<b><span style="color: rgb(102, 51, 0);">(</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">));
<br />
<br /></span></b></pre>Questo tipo di definizione dovrebbe esservi nuova, i servizi sono il sistema attraverso il quale potete aggiungere dei componenti al una lista di elementi facilmente riselezionabili.
<br />In questo modo condividerete un unico servizio spritebatch in tutte le vostre classi/componenti senza doverne ricreare uno nuovo ogni volta. (Vedremo dopo nel file Game.cs come aggiungere un componente ai servizi).
<br />
<br /><span style="font-weight: bold;">AUDIO COMPONENT</span>...............................................................
<br />Componente per la gestione dell'audio. Nonostante non conosciate ancora la logica di gestione dell'audio di XNA (e ammetto che è una delle parti che mi annoia di più), potrete facilmente immaginare come utilizzare questo componente.
<br />Prima di tutto creiamo gli oggetti utili al motore audio di XNA.
<br /><pre><span style="color: rgb(153, 0, 0);"> private</span> AudioEngine audioEngine<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /> private</span> WaveBank waveBank<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /> private</span> SoundBank soundBank<b><span style="color: rgb(102, 51, 0);">;</span></b></pre>Nella funzione initialize vedrete come vengono istanziati i valori presenti qui sopra.
<br /><pre> audioEngine<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> AudioEngine<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(0, 153, 0);">"Content\\gameAudio.xgs"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> waveBank<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> WaveBank<b><span style="color: rgb(102, 51, 0);">(</span></b>audioEngine<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(0, 153, 0);"> "Content\\Wave Bank.xwb"</span><b><span style="color: rgb(102, 51, 0);">);</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>waveBank<b><span style="color: rgb(102, 51, 0);"> !=</span></b> null<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> soundBank<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SoundBank<b><span style="color: rgb(102, 51, 0);">(</span></b>audioEngine<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(0, 153, 0);"> "Content\\Sound Bank.xsb"</span><b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b></pre>Se Aprite il file gameAudio.xap presente nella folder dei contenuti potrete vedere il file che viene generato dal tool XACT, si tratta di un file scritto in un linguaggio simile al C, dove vengono descritti AudioEngine con dei parametri che sinceramente ignoro, WaveBank dove viene preso il riferimento ai file wav ai quali ci appoggeremo, e soundBank dove vengono identificati gli elementi <span style="font-weight: bold;">cue</span> che ci serviranno per riprodurre direttamente i file audio caricati. ( per ora accontentatevi di queste poche righe di spiegazione.. e concentratevi più che altro sulla logica delle scene.. sull'audio ritorneremo).
<br />I riferimenti cue audio presenti in gameAudio.xap sono i seguenti :
<br /><span style="font-style: italic; font-weight: bold;">rpg</span> - <span style="font-style: italic;">suono di un'esplosione</span>
<br /><span style="font-style: italic; font-weight: bold;">sigla</span><span style="font-weight: bold;"> </span>- <span style="font-style: italic;">la mitica sigla iniziale di Battlestar Galactica</span>
<br /><span style="font-style: italic; font-weight: bold;">electro</span> - <span style="font-style: italic;">suono digitale utilizzato per il menu</span>
<br />
<br /><span style="font-weight: bold;">TEXTCOMPONENT....................................................</span>
<br />Questo componente verrà utilizzato per stampare semplici stringhe di testo, in testa alla classe trovate alcuni parametri utili a definire le informazioni di queste stringhe, come colore, testo da stampare, posizione e naturalmente lo spritefont da utilizzare. Il componente ci tornerà utile per stampare qualche elemento della semplice gui grafica, che presenterà la vita e il punteggio.
<br /><pre><i><span style="color: rgb(153, 153, 153);"> //Testo da stampare
<br /></span></i><span style="color: rgb(153, 0, 0);"> protected</span> String text<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> ""</span><b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // Fonts
<br /></span></i><span style="color: rgb(153, 0, 0);"> protected</span> readonly SpriteFont font<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // Colors
<br /></span></i><span style="color: rgb(153, 0, 0);"> protected</span> Color color<b><span style="color: rgb(102, 51, 0);"> =</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>White<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // Menu Position
<br /></span></i><span style="color: rgb(153, 0, 0);"> protected</span> Vector2 position<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">();
<br />
<br /></span></b></pre><span style="font-weight: bold;">SPRITEMANAGER...................................................</span>
<br />Questo direi che lo conosciamo abbastanza bene :P , è l'elemento che gestisce gli sprite presenti nel gioco e alcune logiche come le collisioni tra sprite.
<br />Tra le modifiche apportate a questa classe noterete che è stato aggiunto un'oggetto AudioComponent che servirà per riprodurre il suono delle esplosioni a seguito di una collisione, ecco qui sotto svelato come riprodurre suoni tramite l'AudioComponent:
<br />
<br /><pre> audioComponent<b><span style="color: rgb(102, 51, 0);">.</span></b>PlayCue<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(0, 153, 0);">"rpg"</span><b><span style="color: rgb(102, 51, 0);">);<span style="font-family:Georgia,serif;">
<br /></span></span></b></pre>La funzione PlayCue del componente audio accetta una stringa che rappresenta il nome del Cue da riprodurre (in questo caso l'esplosione).
<br />
<br /><span style="font-weight: bold;">TEXTMENUCOMPONENT..........................................
<br /><span style="font-weight: bold;">Q</span></span>uesto componente viene utilizzato per creare un menu testuale, utilizza una string collection (<span style="font-style: italic;">menuItems</span>) per rappresentare le varie voci.
<br />
<br />E' interessante notare come in questo componente si utilizzi un riferimento alla content pipeline per caricare contenuti direttamente dal componente, in questo modo può essere facilmente riutilizzato in altri programmi senza dover aggiungere ulteriori informazioni nella logica già esistente. Se non avessimo utilizzato questo metodo, avremmo dovuto caricare i contenuti a livello di Game1.cs nella load content, impostandoli inoltre come variabili di classe per poterli raggiungere dai vari componenti.
<br /><pre> ContentManager myCont<b><span style="color: rgb(102, 51, 0);"> =</span></b> game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Setta i font utilizzati
<br /></span></i> regularFont<b><span style="color: rgb(102, 51, 0);"> =</span></b> myCont<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>SpriteFont<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"Arial"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> selectedFont<b><span style="color: rgb(102, 51, 0);"> =</span></b> myCont<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>SpriteFont<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"ArialBig"</span><b><span style="color: rgb(102, 51, 0);">);</span></b> </pre>
<br />
<br />La logica attraverso la quale viene resa "selezionata" una voce di menu è l'incrementale selectedIndex che a seconda della pressione dei tasti freccia su o freccia giù aumenta o diminuisce di uno, e in entrambi i casi genera un suono (funzione update) . Notate che quando si arriva a fondo menu premendo la freccia "giù" si torna alla prima voce e se ci si trova in testa e si preme la freccia "su" si passa all'ultima voce.
<br />
<br /><pre><span style="color: rgb(255, 102, 51);"> bool</span> down<b><span style="color: rgb(102, 51, 0);">,</span></b> up<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // Check input tastiera
<br /></span></i>
<br /> down<b><span style="color: rgb(102, 51, 0);"> = (</span></b>oldKeyboardState<b><span style="color: rgb(102, 51, 0);">.</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Down<b><span style="color: rgb(102, 51, 0);">) &&
<br /> (</span></b>keyboardState<b><span style="color: rgb(102, 51, 0);">.</span></b>IsKeyUp<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Down<b><span style="color: rgb(102, 51, 0);">)));</span></b>
<br />
<br /> up<b><span style="color: rgb(102, 51, 0);"> = (</span></b>oldKeyboardState<b><span style="color: rgb(102, 51, 0);">.</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Up<b><span style="color: rgb(102, 51, 0);">) &&
<br /> (</span></b>keyboardState<b><span style="color: rgb(102, 51, 0);">.</span></b>IsKeyUp<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Up<b><span style="color: rgb(102, 51, 0);">)));</span></b><span style="color: rgb(255, 0, 0);">
<br />
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>down<b><span style="color: rgb(102, 51, 0);"> ||</span></b> up<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> audioComponent<b><span style="color: rgb(102, 51, 0);">.</span></b>PlayCue<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(0, 153, 0);">"electro"</span><b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><span style="color: rgb(255, 0, 0);">
<br />
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>down<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> selectedIndex<b><span style="color: rgb(102, 51, 0);">++;</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>selectedIndex<b><span style="color: rgb(102, 51, 0);"> ==</span></b> menuItems<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> selectedIndex<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }
<br /> }</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>up<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> selectedIndex<b><span style="color: rgb(102, 51, 0);">--;</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>selectedIndex<b><span style="color: rgb(102, 51, 0);"> == -</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> selectedIndex<b><span style="color: rgb(102, 51, 0);"> =</span></b> menuItems<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);"> -</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }
<br /> }</span></b></pre>
<br />Per quanto riguarda la funzione draw viene scorsa la lista menuItems, quando ci si trova a stampare la voce attualmente selezionata si stampa con i parametri "selected", altrimenti con i parametri "regular".
<br />Da notare il trucchetto utilizzato per stampare delle ombre del testo, stampando due volte la stessa voce e facendo si che la stampa a livello inferiore sia leggermente spostata rispetto a quella superiore e quindi non interamente coperta, producendo un effetto ombra.
<br />
<br /><pre><i><span style="color: rgb(153, 153, 153);"> //Scorre tutti gli elementi
<br /></span></i><span style="color: rgb(255, 0, 0);"> for</span><b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(255, 102, 51);">int</span> i<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);"> <</span></b> menuItems<b><span style="color: rgb(102, 51, 0);">.</span></b>Count<b><span style="color: rgb(102, 51, 0);">;</span></b> i<b><span style="color: rgb(102, 51, 0);">++)
<br /> {</span></b>
<br /> SpriteFont font<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Color theColor<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Quando trova l'elemento selezionato associa il font e il color per l'elemento selezionato
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>i<b><span style="color: rgb(102, 51, 0);"> ==</span></b> SelectedIndex<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> font<b><span style="color: rgb(102, 51, 0);"> =</span></b> selectedFont<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> theColor<b><span style="color: rgb(102, 51, 0);"> =</span></b> selectedColor<b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><span style="color: rgb(255, 0, 0);">
<br /> else</span><b><span style="color: rgb(102, 51, 0);">
<br /> {</span></b>
<br /> font<b><span style="color: rgb(102, 51, 0);"> =</span></b> regularFont<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> theColor<b><span style="color: rgb(102, 51, 0);"> =</span></b> regularColor<b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // Disegna l'ombra dell'elemento menu
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawString<b><span style="color: rgb(102, 51, 0);">(</span></b>font<b><span style="color: rgb(102, 51, 0);">,</span></b> menuItems<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">],</span></b><span style="color: rgb(153, 0, 0);">
<br /> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b>position<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);"> +</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b> y<b><span style="color: rgb(102, 51, 0);"> +</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">),</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>Red<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // Disegna l'elemento del menu
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawString<b><span style="color: rgb(102, 51, 0);">(</span></b>font<b><span style="color: rgb(102, 51, 0);">,</span></b> menuItems<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">],</span></b><span style="color: rgb(153, 0, 0);">
<br /> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b>position<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);">,</span></b> y<b><span style="color: rgb(102, 51, 0);">),</span></b> theColor<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br /> y<b><span style="color: rgb(102, 51, 0);"> +=</span></b> font<b><span style="color: rgb(102, 51, 0);">.</span></b>LineSpacing<b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b></pre>
<br />
<br />
<br />Ora che conosciamo i vari componenti torniamo alla descrizione delle scene!
<br />
<br /><span style="font-weight: bold;">STARTSCENE----------------------------------------------------------------------------</span>
<br /><span style="font-weight: bold;">Descrizione:</span> E' la scena iniziale dove, tramite un menu, vengono presentate le azioni disponibili. Questa scena ha un sottofondo musicale e un'immagine di sfondo.
<br /><span style="font-weight: bold;">
<br />Componenti utilizzati:</span>
<br />ImageComponent, TextMenuComponent, AudioComponent
<br />
<br />Analizziamo il costruttore
<br />
<br /><pre><span style="color: rgb(153, 0, 0);"> public</span> StartScene<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> ContentManager startCont<b><span style="color: rgb(102, 51, 0);"> =</span></b> game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Add sfondo tramite componente di tipo Image
<br /></span></i> Texture2D background<b><span style="color: rgb(102, 51, 0);"> =</span></b> startCont<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"battlestar"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> ImageComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">,</span></b> background<b><span style="color: rgb(102, 51, 0);">,</span></b>ImageComponent<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawMode<b><span style="color: rgb(102, 51, 0);">.</span></b>Center<b><span style="color: rgb(102, 51, 0);">));</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // Crea le voci di menu e aggiungo il menu con un componente di tipo TextMenu
<br /></span></i> string<b><span style="color: rgb(102, 51, 0);">[]</span></b> items<b><span style="color: rgb(102, 51, 0);"> = {</span></b><span style="color: rgb(0, 153, 0);"> "Inizia la partita"</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(0, 153, 0);"> "Help"</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(0, 153, 0);"> "Esci dal gioco"</span><b><span style="color: rgb(102, 51, 0);"> };</span></b>
<br /> menu<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> TextMenuComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> menu<b><span style="color: rgb(102, 51, 0);">.</span></b>SetMenuItems<b><span style="color: rgb(102, 51, 0);">(</span></b>items<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>menu<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Recupero lo spritebatch dai servizi
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);"> = (</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Services<b><span style="color: rgb(102, 51, 0);">.</span></b>GetService<b><span style="color: rgb(102, 51, 0);">(</span></b>typeof<b><span style="color: rgb(102, 51, 0);">(</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">));</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Recupero audiocomponente dai servizi
<br /></span></i> audioComponent<b><span style="color: rgb(102, 51, 0);"> = (</span></b>AudioComponent<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Services<b><span style="color: rgb(102, 51, 0);">.</span></b>GetService<b><span style="color: rgb(102, 51, 0);">(</span></b>typeof<b><span style="color: rgb(102, 51, 0);">(</span></b>AudioComponent<b><span style="color: rgb(102, 51, 0);">));
<br /> }</span></b></pre>
<br />Concentriamoci sul metodo attraverso aggiungiamo componenti alla scena, come potete notare utilizziamo
<br />la<span style="font-style: italic;"> </span>funzione add della lista components che viene <span style="font-weight: bold;">ereditata direttamente dalla classe GameScene.</span>
<br />(Chiamamiamo <span style="font-weight: bold;">C</span>omponents.Add e non<span style="font-weight: bold;"> c</span>omponents.add perchè abbiamo definito la proprietà get sempre nella classe GameScene).
<br />A questo punto i componenti aggiunti alla lista components verranno ciclati nei metodi Update e Draw, che nel caso della scena startScene fanno riferimento ai metodi della classe padre, senza alcuna modifica.
<br />
<br />Le funzioni show e hide si occupano semplicemente di modificare i parametri visible e enabled del menu e di far partire o bloccare l'audio.
<br />
<br />
<br /><span style="font-weight: bold;">PLAYSCENE----------------------------------------------------------------------------------
<br />Descrizione:</span>scena dove viene gestito il gioco vero e proprio<span style="font-weight: bold;">
<br />Componenti:</span>TextComponent, ImageComponent, SpriteManager, AudioComponent
<br />
<br />Analizziamo il costruttore
<br /><pre><span style="color: rgb(153, 0, 0);"> public</span> PlayScene<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> ContentManager startCont<b><span style="color: rgb(102, 51, 0);"> =</span></b> game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> score_gui<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> TextComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> life_gui<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> TextComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Aggiunge lo sfondo
<br /></span></i> Texture2D background<b><span style="color: rgb(102, 51, 0);"> =</span></b> startCont<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"universe"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> ImageComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">,</span></b> background<b><span style="color: rgb(102, 51, 0);">,</span></b>ImageComponent<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawMode<b><span style="color: rgb(102, 51, 0);">.</span></b>Center<b><span style="color: rgb(102, 51, 0);">));</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Aggiunge il gestore degli sprite
<br /></span></i> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> SpriteManager<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">));</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Aggiunge i testi per la vita e il punteggio
<br /></span></i> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>life_gui<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>score_gui<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Modifica qualche parametro dell'interfaccia grafica
<br /></span></i> score_gui<b><span style="color: rgb(102, 51, 0);">.</span></b>Position<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">200</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> score_gui<b><span style="color: rgb(102, 51, 0);">.</span></b>Color<b><span style="color: rgb(102, 51, 0);"> =</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>Red<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Recupera lo spriteBatch dai servizi
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);"> = (</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Services<b><span style="color: rgb(102, 51, 0);">.</span></b>GetService<b><span style="color: rgb(102, 51, 0);">(</span></b>typeof<b><span style="color: rgb(102, 51, 0);">(</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">));
<br /> }
<br />
<br />
<br /></span></b></pre>Come per la startScene qui aggiungiamo i vari componenti che farrano parte della scena, impostiamo due istanze del componente che si occupa delle stringhe di testo, che utilizzeremo per stampare punti vita e punteggio totale, aggiungiamo un background e lo sprite manager.... niente di difficile.
<br />Nell'update invece ci occupiamo di tenere tracica di eventuali modifiche nel punteggio o nella vita cambiando il parametro Text dei due oggetti TextComponent.
<br /><pre> life_gui<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Life: "</span><b><span style="color: rgb(102, 51, 0);"> + ((</span></b>Game1<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">).</span></b>Life<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> score_gui<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Score: "</span><b><span style="color: rgb(102, 51, 0);"> + ((</span></b>Game1<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">).</span></b>Score<b><span style="color: rgb(102, 51, 0);">; ;
<br />
<br /></span></b></pre>
<br /><span style="font-weight: bold;">WINSCENE-------------------------------------------------------------------------------
<br />Descrizione:</span>Scena con un messaggio di vittoria
<br /><span style="font-weight: bold;">Componenti:</span>TextComponent, ImageComponent
<br />
<br />Nel file Game1.cs, come vedremo più avanti, viene gestita la logica del punteggio.Quando questo raggiunge un determinato valore si passa ad una schermata di vittoria costrutira tramite la winScene.
<br />Molto semplicemente in questa scena aggiungiamo un'immagine di sfondo e un testo...
<br />
<br /><pre><span style="color: rgb(153, 0, 0);"> public</span> WinScene<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> ContentManager startCont<b><span style="color: rgb(102, 51, 0);"> =</span></b> game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Texture2D background<b><span style="color: rgb(102, 51, 0);"> =</span></b> startCont<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"battlestar"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> winText<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> TextComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> winText<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Congratulazioni! Hai Vinto!"</span><b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> winText<b><span style="color: rgb(102, 51, 0);">.</span></b>Position<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Width<b><span style="color: rgb(102, 51, 0);"> /</span></b><span style="color: rgb(153, 153, 0);"> 2</span><b><span style="color: rgb(102, 51, 0);">-</span></b><span style="color: rgb(153, 153, 0);">50</span><b><span style="color: rgb(102, 51, 0);">,</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Height<b><span style="color: rgb(102, 51, 0);"> /</span></b><span style="color: rgb(153, 153, 0);"> 2</span><b><span style="color: rgb(102, 51, 0);"> +</span></b><span style="color: rgb(153, 153, 0);">30</span><b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Add sfondo
<br /></span></i> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> ImageComponent<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">,</span></b> background<b><span style="color: rgb(102, 51, 0);">,</span></b>
<br /> ImageComponent<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawMode<b><span style="color: rgb(102, 51, 0);">.</span></b>Center<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>winText<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // Get the current spritebatch
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);"> = (</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Services<b><span style="color: rgb(102, 51, 0);">.</span></b>GetService<b><span style="color: rgb(102, 51, 0);">(</span></b>typeof<b><span style="color: rgb(102, 51, 0);">(</span></b>SpriteBatch<b><span style="color: rgb(102, 51, 0);">));
<br /> }</span></b></pre>
<br /><span style="font-weight: bold;">HELPSCENE---------------------------------------------------------------------------</span>
<br /><span style="font-weight: bold;">Descrizione: </span>Scena volutamente vuota... creata per i vostri esperimenti!
<br /><span style="font-weight: bold;">Componenti:</span> per ora solo ImageComponent
<br />
<br />Questa scena è assolutamente inutile.... ho aggiunto solo l'immagine di sfondo presente già nella PlayScene... potrete dunque sfruttarla per i vostri test.
<br />
<br />
<br />
<br />
<br />Per quanto riguarda le scene è tutto, a questo punto passiamo al file Game1.cs dove verranno effettivamente caricate e gestite le scene viste sopra.
<br />In testa al file istanziamo alcuni oggetti/variabili
<br /><pre><i><span style="color:#999999;"> //Init----------------------------------------
<br /></span></i> GraphicsDeviceManager graphics<b><span style="color:#663300;">;</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color:#663300;">;</span></b>
<br /> AudioComponent audioComponent<b><span style="color:#663300;">;</span></b><i><span style="color:#999999;">
<br />
<br /> //Variabili globali---------------------------
<br /></span></i><span style="color:#ff6633;"> int</span> life<b><span style="color:#663300;"> =</span></b><span style="color:#999900;"> 30</span><b><span style="color:#663300;">;</span></b><span style="color:#ff6633;">
<br /> int</span> score<b><span style="color:#663300;"> =</span></b><span style="color:#999900;"> 0</span><b><span style="color:#663300;">;</span></b><span style="color:#ff6633;">
<br /> int</span> winScore<b><span style="color:#663300;"> =</span></b><span style="color:#999900;"> 10</span><b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br /> protected</span> KeyboardState oldKeyboardState<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br /> protected</span> GamePadState oldGamePadState<b><span style="color:#663300;">;</span></b><i><span style="color:#999999;">
<br />
<br /> //Scene--------------------------------------
<br /></span></i> StartScene startscene<b><span style="color:#663300;">;</span></b>
<br /> PlayScene playscene<b><span style="color:#663300;">;</span></b>
<br /> HelpScene helpscene<b><span style="color:#663300;">;</span></b>
<br /> WinScene winscene<b><span style="color:#663300;">;</span></b>
<br /> GameScene activescene<b><span style="color:#663300;">;</span></b></pre>Nelle ultime righe qui sopra vedete che istanziamo gli oggetti che rappresentano le varie scene che ci serviranno e che creiamo una scena in più chiamata<span style="font-weight: bold;"> activescene</span> di tipo GameScene e quindi potrà essere associata a qualsiasi scena.
<br />Nella funzione initialize inizializiamo il componente audio, e vediamo finalmente <span style="font-weight: bold;">come si aggiunge un componente ai servizi </span>usando la funzione AddService<span style="font-weight: bold;">:
<br /></span><pre><span style="color:#990000;"> protected</span> override<span style="color:#ff6633;"> void</span> Initialize<b><span style="color:#663300;">()
<br /> {</span></b>
<br /> audioComponent<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> AudioComponent<b><span style="color:#663300;">(</span></b><span style="color:#990000;">this</span><b><span style="color:#663300;">);</span></b>
<br /> Services<b><span style="color:#663300;">.</span></b>AddService<b><span style="color:#663300;">(</span></b>typeof<b><span style="color:#663300;">(</span></b>AudioComponent<b><span style="color:#663300;">),</span></b> audioComponent<b><span style="color:#663300;">);</span></b>
<br />
<br /> Components<b><span style="color:#663300;">.</span></b>Add<b><span style="color:#663300;">(</span></b>audioComponent<b><span style="color:#663300;">);</span></b>
<br /> base<b><span style="color:#663300;">.</span></b>Initialize<b><span style="color:#663300;">();
<br /> }</span></b></pre>Una piccola nota sul <span style="font-style: italic;">Components.Add(): </span>In questo caso non state usando la stessa Components.Add che utilizzavate per le scene.... in questo caso stiamo usando la collection di base di XNA che serve appunto per registrare i nostri componenti nel gameloop.
<br />Per quanto riguarda la funzione LoadContent, aggiungiamo lo spritebatch ai servizi, istanziamo le scene , registriamo i componenti e rendiamo attiva la scena StartScene (quella con il menu) associandola alla scena activeScene.
<br />
<br />Date una sbirciatina alla funzione update... vedrete che richiama la funzione HandleScenesInput();
<br />Lo scopo di questa funzione è quello di gestire l'input in maniera differente a seconda della scena nella quale ci si trova. (non gestisce gli spostamenti dell'astronave però... quelli li gestiamo nello spritemanager)
<br /><pre><i><span style="color:#999999;"> //Gestisce gli input delle scene
<br /></span></i><span style="color:#990000;"> private</span><span style="color:#ff6633;"> void</span> HandleScenesInput<b><span style="color:#663300;">()
<br /> {</span></b><i><span style="color:#999999;">
<br /> // Handle Start Scene Input
<br /></span></i><span style="color:#ff0000;"> if</span><b><span style="color:#663300;"> (</span></b>activescene<b><span style="color:#663300;"> ==</span></b> startscene<b><span style="color:#663300;">)
<br /> {</span></b>
<br /> HandleStartSceneInput<b><span style="color:#663300;">();
<br /> }</span></b><i><span style="color:#999999;">
<br /> // Handle Help Scene Input
<br /></span></i><span style="color:#ff0000;"> else if</span><b><span style="color:#663300;"> (</span></b>activescene<b><span style="color:#663300;"> ==</span></b> helpscene<b><span style="color:#663300;">)
<br /> {</span></b><span style="color:#ff0000;">
<br /> if</span><b><span style="color:#663300;"> (</span></b>CheckEnterA<b><span style="color:#663300;">())
<br /> {</span></b>
<br /> ShowScene<b><span style="color:#663300;">(</span></b>startscene<b><span style="color:#663300;">);
<br /> }
<br /> }</span></b><i><span style="color:#999999;">
<br /> // Handle Action Scene Input
<br /></span></i><span style="color:#ff0000;"> else if</span><b><span style="color:#663300;"> (</span></b>activescene<b><span style="color:#663300;"> ==</span></b> playscene<b><span style="color:#663300;">)
<br /> {</span></b>
<br /> HandleActionInput<b><span style="color:#663300;">();
<br /> }
<br /> }</span></b></pre>
<br />In base alla scena nella quale ci troviamo viene richiamata una funzione piuttosto che un'altra...
<br />Le funzioni da prendere in considerazione sono le seguenti:
<br /><span style="font-weight: bold;">handleStartSceneInput()</span>, che tramite la funzione <span style="font-weight: bold;">checkEnterA()</span> controlla se viene premuto il tasto invio o il tasto A del pad... e in questo caso a seconda della voce di menu momentaneamente attiva manda a una scena definita. La gestione della pressione dei tasti freccia su e freccia giù è impostata all'interno del componente TextMenuComponent.
<br /><span style="font-weight: bold;">HandleActionInput();</span> che durante la fase di gioco controlla se viene premuto il tasto "esc" e in tal caso riporta alla start scene.
<br />
<br />Per attivare una scena viene usata la funzione helper ShowScene(scenadaattivare); che si occupa di disattivare la scena attiva e rendere attiva quella passata alal funzione.
<br />
<br />Le ultime funzioni da analizzare sono le propiretà get e set Life e Score, entrambe vengono richiamate dal componente SpriteManager durante il ciclo di Update nel caso in cui ci siano collisioni (decrementando Life e Score) e nel caso in cui un'astronave nemica esca dallo spazio di gioco (incrementando Score).
<br />La Score definisce che se il punteggio superà winScore (definito in testa a Game1.cs) allora bisogna attivare la scena winScene.
<br />
<br />A questo punto penso che abbiate in testa un marasma di informazioni.... Faccio un breve riassunto che spero vi possa aiutare per focalizzare le informazioni:
<br />
<br />Lo scopo della lezione è creare una navigazione tra diverse scene del programma,
<br />fondamentalmente 3 scene - Un menu - Un gamePlay - Una schermata finale.
<br />Ogni scena è composta da diversi componenti ( menu, immagini, sprite, testi, suoni) che vengono aggiornati e disegnati unicamente quando la scena è attiva. L'attivazione di una scena è definita nel file game1.cs grazie a un gestore dell'input (che per alcune scene come PlayScene StartScene viene anche controllato direttamente dal componente textmenu e spritemanager) e grazie a una logica di gioco che fa si che ad un determinato punteggio venga attivata la scena di fine partita.
<br />
<br />GAME ---------->LOOP
<br /> |---------- SCENA ATTIVA---------->LOOP COMPONENTI SCENA
<br /> |-----------Singolo Componente
<br />
<br />
<br />Con questo post vi saluterò per un pò, dato che preparerò un tutorial come questo per la creazione di un videogame 3d.... spero di postare i primi articoli sul 3d tra un mesetto circa, comunque passerò spesso dal blog, se avete bisogno chiarimenti ho se volete segnalarmi delle correzioni io sono qui :D
<br />
<br />Ciao a tutti !!
<br />A prestissimo!!!
<br />
<br /><span style="font-weight: bold;">CODICE SORGENTE: </span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/6.2dgame.zip">6.2dgame.zip</a>
<br />
<br /><script>function fbs_click() {u=location.href;t=document.title;window.open('http://www.facebook.com/sharer.php?u='+encodeURIComponent(u)+'&t='+encodeURIComponent(t),'sharer','toolbar=0,status=0,width=626,height=436');return false;}</script><a href="http://www.facebook.com/share.php?u=<url>" onclick="return fbs_click()" target="_blank"><img src="http://b.static.ak.fbcdn.net/images/share/facebook_share_icon.gif?8:26981" alt="" /></a>
<br />Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com9tag:blogger.com,1999:blog-1511468527759599388.post-5673837995644633412009-03-12T14:48:00.000-07:002011-10-05T00:46:39.712-07:008) Xna Videogame Tutorial: Generazione Automatica CasualeWoooow che titolone che ha questo post...
<br />Sono veramente contento di essere arrivato fino a questo punto, pensavo che mi sarei rotto le palle mooooolto prima, invece vedere che si sono tutti i giorni dei lettori (grazie google Analytics) mi mette voglia di scrivere... lasciate qualche commento come segno di vita dai! fa venire voglia di scrivere sapere che c'è qualcuno interessato :D
<br />
<br />Comunque, tornando a noi, ci terrei ad inserire subito qui sotto il video di questa lezione perchè a mio parere fa venire voglia di leggerla e concluderla :D
<br />
<br /><span style="font-weight: bold;">Anteprima Video </span>
<br /><object width="640" height="505"><param name="movie" value="http://www.youtube.com/v/IWDIwo27Mb0&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/IWDIwo27Mb0&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="640" height="505"></embed></object>
<br />
<br />L'argomento principale come da mega titolo è la generazione casuale di sprite, se avete seguito le altre lezioni saprete che ad ogni collisione vengono decrementati punti vita, che siamo in grado di pilotare la nostra astronave e che abbiamo uno spritemanager per gestire le grafiche 2d.
<br />Quello che aggiungeremo ora sarà un sistema temporizzato che permetterà la generazione in posizioni casuali di altri sprite. Oltretutto produrremmo due tipologie di sprite in base alla velocità delle astronavi.
<br />
<br />Come potete vedere gli sprite che ho utilizzato sono differenti da quelli presenti negli altri tutorial, volevo dare un pò più di gusto a questa lezione e ho deciso di utilizzare delle astronavi di Battlestar Galactica così a qualche mio amico verrà sicuuuramente voglia di seguire questi turorial.... :P( ne approfitto per ringraziare martin studio sito dal quale ho reperito questi ottimi sprite <a href="http://martinstudio.kings-field.com/">http://martinstudio.kings-field.com/</a> sono fatti veramente bene!!! ).
<br />
<br />Per modificare le immagini aggiunte nelle precedenti lezioni basta andare nel punto dove avete salvato il progetto (solitamente Documenti\Visual Studio 2008\Projects\) arrivare alla cartella content del progetto e sostituire le immagini mantenendo gli stesis nomi (per evitare di dover modificare il codice). Le immagini le trovate nei sorgenti a fondo pagina o direttamente al link segnalato sopra.
<br />
<br />A questo punto partirei spedito con il codice senza perdere altro tempo!
<br />Partiamo dal file Game1.cs qui ho aggiunto un'immagine di sfondo e il riferimento all'oggetto rnd di tipo Random sul quale faremo affidamento per generare i nostri valori casuali.
<br />Come al solito copio tutto il codice per darvi una visibilità magigore di quello che ho modificato (segno in grasseto le modifiche)
<br />
<br /><span style="font-weight: bold;">GAME1</span>
<br /><pre><span style="color:#990000;">using</span> System<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> System<b><span style="color:#663300;">.</span></b>Collections<b><span style="color:#663300;">.</span></b>Generic<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> System<b><span style="color:#663300;">.</span></b>Linq<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Audio<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Content<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>GamerServices<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Graphics<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Input<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Media<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Net<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Storage<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />
<br />namespace</span> input<b><span style="color:#663300;">
<br />{</span></b><span style="color:#990000;">
<br /> public class</span> Game1<b><span style="color:#663300;"> :</span></b> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Game<b><span style="color:#663300;">
<br /> {</span></b>
<br /> GraphicsDeviceManager graphics<b><span style="color:#663300;">;</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color:#663300;">;</span></b><span style="color:#ff6633;">
<br /> int</span> life<b><span style="color:#663300;">;</span></b><i><span style="color:#999999;">//Vite del giocatore
<br /></span></i> SpriteFont gui_life<b><span style="color:#663300;">;</span></b><i><span style="color:#999999;">//GUI
<br /></span></i> <b style="font-weight: bold;">Texture2D tex_universe<span style="color:#663300;">;</span></b><i><span style="color:#999999;"><span style="font-weight: bold;">//Background universo</span>
<br />
<br /> //Proprietà per Random
<br /></span></i><span style="color:#990000;"> <span style="font-weight: bold;">public</span></span><span style="font-weight: bold;"> Random rnd</span><b style="font-weight: bold;"><span style="color:#663300;"> {</span></b><span style="font-weight: bold;"> get</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><span style="font-weight: bold;color:#990000;" > private</span><span style="font-weight: bold;"> set</span><b style="font-weight: bold;"><span style="color:#663300;">; }</span></b><span style="color:#990000;">
<br />
<br /> public</span> Game1<b><span style="color:#663300;">()
<br /> {</span></b>
<br /> graphics<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> GraphicsDeviceManager<b><span style="color:#663300;">(</span></b><span style="color:#990000;">this</span><b><span style="color:#663300;">);</span></b>
<br /> Content<b><span style="color:#663300;">.</span></b>RootDirectory<b><span style="color:#663300;"> =</span></b><span style="color:#009900;"> "Content"</span><b><span style="color:#663300;">;</span></b>
<br /> <b style="font-weight: bold;">rnd<span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#990000;" > new</span><span style="font-weight: bold;"> Random</span><b><span style="color:#663300;"><span style="font-weight: bold;">();</span>
<br />
<br /> }</span></b><span style="color:#990000;">
<br /> protected</span> override<span style="color:#ff6633;"> void</span> Initialize<b><span style="color:#663300;">()
<br /> {</span></b>
<br /> SpriteManager spritemanager<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> SpriteManager<b><span style="color:#663300;">(</span></b><span style="color:#990000;">this</span><b><span style="color:#663300;">);</span></b>
<br /> Components<b><span style="color:#663300;">.</span></b>Add<b><span style="color:#663300;">(</span></b>spritemanager<b><span style="color:#663300;">);</span></b>
<br /> life<b><span style="color:#663300;"> =</span></b><span style="color:#999900;"> 100</span><b><span style="color:#663300;">;</span></b>
<br />
<br /> base<b><span style="color:#663300;">.</span></b>Initialize<b><span style="color:#663300;">();
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> protected</span> override<span style="color:#ff6633;"> void</span> LoadContent<b><span style="color:#663300;">()
<br /> {</span></b><i><span style="color:#999999;">
<br /> // Create a new SpriteBatch, which can be used to draw textures.
<br /></span></i> spriteBatch<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> SpriteBatch<b><span style="color:#663300;">(</span></b>GraphicsDevice<b><span style="color:#663300;">);</span></b>
<br /> <b style="font-weight: bold;">tex_universe<span style="color:#663300;">=</span></b><span style="font-weight: bold;"> Content</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Load</span><b style="font-weight: bold;"><span style="color:#663300;"><</span></b><span style="font-weight: bold;">Texture2D</span><b style="font-weight: bold;"><span style="color:#663300;">>(</span></b><span style="font-weight: bold;">@</span><span style="font-weight: bold;color:#009900;" >"universe"</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b>
<br /> gui_life<b><span style="color:#663300;"> =</span></b> Content<b><span style="color:#663300;">.</span></b>Load<b><span style="color:#663300;"><</span></b>SpriteFont<b><span style="color:#663300;">>(</span></b><span style="color:#009900;">"Arial"</span><b><span style="color:#663300;">);
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> protected</span> override<span style="color:#ff6633;"> void</span> UnloadContent<b><span style="color:#663300;">()
<br /> {
<br /> }</span></b><span style="color:#990000;">
<br />
<br />
<br /> protected</span> override<span style="color:#ff6633;"> void</span> Update<b><span style="color:#663300;">(</span></b>GameTime gameTime<b><span style="color:#663300;">)
<br /> {</span></b><span style="color:#ff0000;">
<br /> if</span><b><span style="color:#663300;"> (</span></b>GamePad<b><span style="color:#663300;">.</span></b>GetState<b><span style="color:#663300;">(</span></b>PlayerIndex<b><span style="color:#663300;">.</span></b>One<b><span style="color:#663300;">).</span></b>Buttons<b><span style="color:#663300;">.</span></b>Back<b><span style="color:#663300;"> ==</span></b> ButtonState<b><span style="color:#663300;">.</span></b>Pressed<b><span style="color:#663300;">)</span></b><span style="color:#990000;">
<br /> this</span><b><span style="color:#663300;">.</span></b>Exit<b><span style="color:#663300;">();</span></b>
<br />
<br /> base<b><span style="color:#663300;">.</span></b>Update<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> protected</span> override<span style="color:#ff6633;"> void</span> Draw<b><span style="color:#663300;">(</span></b>GameTime gameTime<b><span style="color:#663300;">)
<br /> {</span></b>
<br /> GraphicsDevice<b><span style="color:#663300;">.</span></b>Clear<b><span style="color:#663300;">(</span></b>Color<b><span style="color:#663300;">.</span></b>CornflowerBlue<b><span style="color:#663300;">);</span></b>
<br />
<br />
<br /> spriteBatch<b><span style="color:#663300;">.</span></b>Begin<b><span style="color:#663300;">();</span></b>
<br /><span style="font-weight: bold;"> spriteBatch</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Draw</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">tex_universe</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#990000;" >
<br /> new</span><span style="font-weight: bold;"> Rectangle</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;color:#999900;" >0</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#999900;" >0</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;">Window</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">ClientBounds</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Width</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;">Window</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">ClientBounds</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Height</span><b style="font-weight: bold;"><span style="color:#663300;">),</span></b><span style="font-weight: bold;">Color</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">White</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b>
<br /><span style="font-weight: bold;"> spriteBatch</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">DrawString</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">gui_life</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#009900;" > "LIFE: "</span><b style="font-weight: bold;"><span style="color:#663300;"> +</span></b><span style="font-weight: bold;"> life</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#990000;" > new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;color:#999900;" >10</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#999900;" > 10</span><b style="font-weight: bold;"><span style="color:#663300;">),</span></b><span style="font-weight: bold;"> Color</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">White</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b>
<br /> spriteBatch<b><span style="color:#663300;">.</span></b>End<b><span style="color:#663300;">();</span></b>
<br />
<br />
<br /> base<b><span style="color:#663300;">.</span></b>Draw<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> public</span><span style="color:#ff6633;"> int</span> Life<b><span style="color:#663300;"> {</span></b>
<br /> get<b><span style="color:#663300;"> {</span></b><span style="color:#ff0000;"> return</span> life<b><span style="color:#663300;">; }</span></b>
<br /> set<b><span style="color:#663300;"> {</span></b>
<br /> life<b><span style="color:#663300;"> =</span></b> value<b><span style="color:#663300;">;</span></b><span style="color:#ff0000;">
<br /> if</span><b><span style="color:#663300;"> (</span></b>life<b><span style="color:#663300;"> ==</span></b><span style="color:#999900;"> 0</span><b><span style="color:#663300;">) {</span></b>
<br /> Exit<b><span style="color:#663300;">();
<br /> }
<br /> }
<br /> }</span></b>
<br /></pre>
<br />Non mi dilungo troppo sull'inserimento dell'<span style="font-weight: bold;">immagine di sfondo</span>, semplicemente aggiungete un contentuto immagine nei content e lo inserite tramite spritebatch prima di disegnare la stringa della vita (in questo modo verrà stampato prima di quest'ultima che si posizionerà al livello superiore).
<br />Per quanto riguarda l'oggetto <span style="font-weight: bold;">rnd</span>, molto semplicemente ho aggiunto una proprietà set e get in testa e ho istanziato l'oggetto nel costruttore, come già anticipato utilizzeremo le funzionalità della classe random per generare numeri casuali.
<br />
<br />Ora entriamo nello spritemanager dove si presentano le vere modifiche!
<br />Eccovi il codice:
<br />
<br /><span style="font-weight: bold;">SPRITEMANAGER</span>
<br /><pre><span style="color:#990000;">using</span> System<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> System<b><span style="color:#663300;">.</span></b>Collections<b><span style="color:#663300;">.</span></b>Generic<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> System<b><span style="color:#663300;">.</span></b>Linq<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Audio<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Content<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>GamerServices<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Graphics<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Input<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Media<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Net<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />using</span> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>Storage<b><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />
<br />
<br />namespace</span> input<b><span style="color:#663300;">
<br />{</span></b><i><span style="color:#999999;">
<br />
<br /></span></i><span style="color:#990000;"> public class</span> SpriteManager<b><span style="color:#663300;"> :</span></b> Microsoft<b><span style="color:#663300;">.</span></b>Xna<b><span style="color:#663300;">.</span></b>Framework<b><span style="color:#663300;">.</span></b>DrawableGameComponent<b><span style="color:#663300;">
<br /> {</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color:#663300;">;</span></b>
<br /> List<b><span style="color:#663300;"><</span></b>Sprite<b><span style="color:#663300;">></span></b> spriteList<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> List<b><span style="color:#663300;"><</span></b>Sprite<b><span style="color:#663300;">>();</span></b>
<br /> ControlledSprite player<b><span style="color:#663300;">;</span></b>
<br /> Texture2D tex1<b><span style="color:#663300;">,</span></b> tex2<b><span style="color:#663300;">,</span></b> texp<b><span style="color:#663300;">;</span></b>
<br /> Vector2 posp<b><span style="color:#663300;">;</span></b><i><span style="color:#999999;">
<br />
<br /><span style="font-weight: bold;"> //tempi di attesa minimi e massimi per lo spawn dei nemici</span>
<br /></span></i><span style="font-weight: bold;color:#ff6633;" > int</span><span style="font-weight: bold;"> minEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#999900;" > 100</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><i style="font-weight: bold;"><span style="color:#999999;">//Millisecondi
<br /></span></i><span style="font-weight: bold;color:#ff6633;" > int</span><span style="font-weight: bold;"> maxEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#999900;" > 600</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><i style="font-weight: bold;"><span style="color:#999999;">//Millisecondi
<br /></span></i><span style="font-weight: bold;color:#ff6633;" > int</span><span style="font-weight: bold;"> nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#999900;" > 0</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />
<br /> public</span> SpriteManager<b><span style="color:#663300;">(</span></b>Game game<b><span style="color:#663300;">)
<br /> :</span></b> base<b><span style="color:#663300;">(</span></b>game<b><span style="color:#663300;">)
<br /> {</span></b><i><span style="color:#999999;">
<br /> // TODO: Construct any child components here
<br /></span></i><b><span style="color:#663300;"> }</span></b><span style="color:#990000;">
<br />
<br /> public</span> override<span style="color:#ff6633;"> void</span> Initialize<b><span style="color:#663300;">()
<br /> {</span></b><i><span style="color:#999999;">
<br /> //Lasciamo solo la posizione iniziale del player
<br /></span></i> posp<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> Vector2<b><span style="color:#663300;">(</span></b><span style="color:#996600;">500.0f</span><b><span style="color:#663300;">,</span></b><span style="color:#996600;"> 400.0f</span><b><span style="color:#663300;">);</span></b><i><span style="color:#999999;">
<br />
<br /><span style="font-weight: bold;"> //impostiamo il prossimo spawn</span>
<br /></span></i><span style="font-weight: bold;"> resetTimer</span><b style="font-weight: bold;"><span style="color:#663300;">();</span></b>
<br /> base<b><span style="color:#663300;">.</span></b>Initialize<b><span style="color:#663300;">();
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> protected</span> override<span style="color:#ff6633;"> void</span> LoadContent<b><span style="color:#663300;">()
<br /> {</span></b>
<br /> tex1<b><span style="color:#663300;"> =</span></b> Game<b><span style="color:#663300;">.</span></b>Content<b><span style="color:#663300;">.</span></b>Load<b><span style="color:#663300;"><</span></b>Texture2D<b><span style="color:#663300;">>(</span></b><span style="color:#009900;">"enemy"</span><b><span style="color:#663300;">);</span></b>
<br /> tex2<b><span style="color:#663300;"> =</span></b> Game<b><span style="color:#663300;">.</span></b>Content<b><span style="color:#663300;">.</span></b>Load<b><span style="color:#663300;"><</span></b>Texture2D<b><span style="color:#663300;">>(</span></b><span style="color:#009900;">"enemy2"</span><b><span style="color:#663300;">);</span></b>
<br /> texp<b><span style="color:#663300;"> =</span></b> Game<b><span style="color:#663300;">.</span></b>Content<b><span style="color:#663300;">.</span></b>Load<b><span style="color:#663300;"><</span></b>Texture2D<b><span style="color:#663300;">>(</span></b><span style="color:#009900;">"spaceship"</span><b><span style="color:#663300;">);</span></b>
<br /> spriteBatch<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> SpriteBatch<b><span style="color:#663300;">(</span></b>Game<b><span style="color:#663300;">.</span></b>GraphicsDevice<b><span style="color:#663300;">);</span></b>
<br />
<br /> player<b><span style="color:#663300;"> =</span></b><span style="color:#990000;"> new</span> ControlledSprite<b><span style="color:#663300;">(</span></b>texp<b><span style="color:#663300;">,</span></b> posp<b><span style="color:#663300;">,</span></b><span style="color:#990000;"> new</span> Vector2<b><span style="color:#663300;">(</span></b><span style="color:#996600;">3.0f</span><b><span style="color:#663300;">,</span></b><span style="color:#996600;"> 3.0f</span><b><span style="color:#663300;">));</span></b>
<br /> base<b><span style="color:#663300;">.</span></b>LoadContent<b><span style="color:#663300;">();
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> public</span> override<span style="color:#ff6633;"> void</span> Update<b><span style="color:#663300;">(</span></b>GameTime gameTime<b><span style="color:#663300;">)
<br /> {</span></b><i><span style="color:#999999;">
<br /> //Aggiorno il giocatore
<br /></span></i> player<b><span style="color:#663300;">.</span></b>Update<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);</span></b><i><span style="color:#999999;">
<br />
<br /><span style="font-weight: bold;"> //Sotraggo il tempo passato dallo spawn time</span>
<br /></span></i><span style="font-weight: bold;"> nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> -=</span></b><span style="font-weight: bold;"> gameTime</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">ElapsedGameTime</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Milliseconds</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><i style="font-weight: bold;"><span style="color:#999999;">
<br /> //Se lo spawn time è sceso sotto zero, genero il nuovo nemico
<br /></span></i><span style="font-weight: bold;color:#ff0000;" > if</span><b style="font-weight: bold;"><span style="color:#663300;"> (</span></b><span style="font-weight: bold;">nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> <</span></b><span style="font-weight: bold;color:#999900;" > 0</span><b style="font-weight: bold;"><span style="color:#663300;">) {</span></b>
<br /><span style="font-weight: bold;"> spawnEnemy</span><b style="font-weight: bold;"><span style="color:#663300;">();
<br /> }</span></b><i><span style="color:#999999;">
<br />
<br /> //Aggiorno tutti gli elementi della lista, al posto del foreach usiamo un for
<br /></span></i><span style="color:#ff0000;"> for</span><b><span style="color:#663300;"> (</span></b><span style="color:#ff6633;">int</span> i<b><span style="color:#663300;"> =</span></b><span style="color:#999900;"> 0</span><b><span style="color:#663300;">;</span></b> i<b><span style="color:#663300;"> <</span></b> spriteList<b><span style="color:#663300;">.</span></b>Count<b><span style="color:#663300;">;</span></b> i<b><span style="color:#663300;">++) {</span></b>
<br /> Sprite s<b><span style="color:#663300;"> =</span></b> spriteList<b><span style="color:#663300;">[</span></b>i<b><span style="color:#663300;">];</span></b>
<br />
<br /> s<b><span style="color:#663300;">.</span></b>Update<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);</span></b><i><span style="color:#999999;">
<br /> //Controllo se uno degli sprite nemici collide contro il giocatore
<br /></span></i><span style="color:#ff0000;"> if</span><b><span style="color:#663300;"> (</span></b>s<b><span style="color:#663300;">.</span></b>collisionRect<b><span style="color:#663300;">.</span></b>Intersects<b><span style="color:#663300;">(</span></b>player<b><span style="color:#663300;">.</span></b>collisionRect<b><span style="color:#663300;">)) {</span></b><i><span style="color:#999999;">
<br /> //Esco dal gioco
<br /></span></i><b><span style="color:#663300;"> --((</span></b>Game1<b><span style="color:#663300;">)</span></b>Game<b><span style="color:#663300;">).</span></b>Life<b><span style="color:#663300;">;</span></b>
<br /> spriteList<b><span style="color:#663300;">.</span></b>RemoveAt<b><span style="color:#663300;">(</span></b>i<b><span style="color:#663300;">);
<br /> --</span></b>i<b><span style="color:#663300;">;
<br /> }</span></b><span style="color:#ff0000;">
<br />
<br /><span style="font-weight: bold;"> if</span></span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">s</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">OutOfView</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Window</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">ClientBounds</span><b style="font-weight: bold;"><span style="color:#663300;">)){</span></b><span style="font-weight: bold;"> </span>
<br /><span style="font-weight: bold;"> spriteList</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">RemoveAt</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">i</span><b style="font-weight: bold;"><span style="color:#663300;">);
<br /> --</span></b><span style="font-weight: bold;">i</span><b><span style="color:#663300;"><span style="font-weight: bold;">;</span>
<br /><span style="font-weight: bold;"> }</span>
<br />
<br /> }</span></b>
<br /> base<b><span style="color:#663300;">.</span></b>Update<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);
<br /> }</span></b><span style="color:#990000;">
<br />
<br /> public</span> override<span style="color:#ff6633;"> void</span> Draw<b><span style="color:#663300;">(</span></b>GameTime gameTime<b><span style="color:#663300;">)
<br /> {</span></b>
<br /> spriteBatch<b><span style="color:#663300;">.</span></b>Begin<b><span style="color:#663300;">();</span></b><i><span style="color:#999999;">
<br /> //Disegno il giocatore
<br /></span></i>
<br /> player<b><span style="color:#663300;">.</span></b>Draw<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">,</span></b>spriteBatch<b><span style="color:#663300;">);</span></b><i><span style="color:#999999;">
<br /> //Disegno tutti gli elementi della lista
<br /></span></i> foreach<b><span style="color:#663300;"> (</span></b>Sprite s in spriteList<b><span style="color:#663300;">)
<br /> {</span></b>
<br /> s<b><span style="color:#663300;">.</span></b>Draw<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">,</span></b>spriteBatch<b><span style="color:#663300;">);
<br /> }</span></b>
<br /> base<b><span style="color:#663300;">.</span></b>Draw<b><span style="color:#663300;">(</span></b>gameTime<b><span style="color:#663300;">);</span></b>
<br /> spriteBatch<b><span style="color:#663300;">.</span></b>End<b><span style="color:#663300;">();
<br /> }</span></b><span style="color:#990000;">
<br />
<br /><span style="font-weight: bold;"> private</span></span><span style="font-weight: bold;color:#ff6633;" > void</span><span style="font-weight: bold;"> resetTimer</span><b style="font-weight: bold;"><span style="color:#663300;">() {</span></b><i style="font-weight: bold;"><span style="color:#999999;">
<br /> //Imposta il tempo del prossimo spawn
<br /></span></i><span style="font-weight: bold;"> nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> = ((</span></b><span style="font-weight: bold;">Game1</span><b style="font-weight: bold;"><span style="color:#663300;">)</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">).</span></b><span style="font-weight: bold;">rnd</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Next</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">minEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;"> maxEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;">);
<br />
<br /> }</span></b><i style="font-weight: bold;"><span style="color:#999999;">
<br />
<br /> //Genera un nuovo nemico se il tempo di spawn è passato
<br /></span></i><span style="font-weight: bold;color:#990000;" > private</span><span style="font-weight: bold;color:#ff6633;" > void</span><span style="font-weight: bold;"> spawnEnemy</span><b style="font-weight: bold;"><span style="color:#663300;">() {</span></b><span style="font-weight: bold;color:#ff6633;" >
<br /> int</span><span style="font-weight: bold;"> xpos</span><b style="font-weight: bold;"><span style="color:#663300;"> = ((</span></b><span style="font-weight: bold;">Game1</span><b style="font-weight: bold;"><span style="color:#663300;">)</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">).</span></b><span style="font-weight: bold;">rnd</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Next</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;color:#999900;" >0</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#999900;" > 600</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b><span style="font-weight: bold;color:#ff6633;" >
<br /> int</span><span style="font-weight: bold;"> xspeed</span><b style="font-weight: bold;"><span style="color:#663300;"> = ((</span></b><span style="font-weight: bold;">Game1</span><b style="font-weight: bold;"><span style="color:#663300;">)</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">).</span></b><span style="font-weight: bold;">rnd</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Next</span><b style="font-weight: bold;"><span style="color:#663300;">(-</span></b><span style="font-weight: bold;color:#999900;" >3</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#999900;" > 3</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b><span style="font-weight: bold;color:#ff6633;" >
<br /> int</span><span style="font-weight: bold;"> yspeed</span><b style="font-weight: bold;"><span style="color:#663300;"> = ((</span></b><span style="font-weight: bold;">Game1</span><b style="font-weight: bold;"><span style="color:#663300;">)</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">).</span></b><span style="font-weight: bold;">rnd</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Next</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;color:#999900;" >2</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;color:#999900;" > 7</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b>
<br /><span style="font-weight: bold;"> Texture2D texture</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><span style="font-weight: bold;color:#ff0000;" >
<br />
<br /> if</span><b style="font-weight: bold;"><span style="color:#663300;"> (</span></b><span style="font-weight: bold;">yspeed</span><b style="font-weight: bold;"><span style="color:#663300;"> ></span></b><span style="font-weight: bold;color:#999900;" > 5</span><b style="font-weight: bold;"><span style="color:#663300;">)
<br /> {</span></b>
<br /><span style="font-weight: bold;"> texture</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;"> tex2</span><b style="font-weight: bold;"><span style="color:#663300;">;
<br /> }</span></b><span style="font-weight: bold;color:#ff0000;" >
<br /> else</span><b style="font-weight: bold;"><span style="color:#663300;"> {</span></b>
<br /><span style="font-weight: bold;"> texture</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;"> tex1</span><b style="font-weight: bold;"><span style="color:#663300;">;
<br /> }</span></b>
<br />
<br /><span style="font-weight: bold;"> Vector2 speed</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#990000;" > new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">xspeed</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;">yspeed</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b>
<br /><span style="font-weight: bold;"> Vector2 position</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#990000;" > new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">xpos</span><b style="font-weight: bold;"><span style="color:#663300;">,-</span></b><span style="font-weight: bold;color:#999900;" >50</span><b style="font-weight: bold;"><span style="color:#663300;">);</span></b>
<br />
<br /><span style="font-weight: bold;"> spriteList</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Add</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;color:#990000;" >new</span><span style="font-weight: bold;"> AutoSprite</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">texture</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;"> position</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;"> speed</span><b style="font-weight: bold;"><span style="color:#663300;">));</span></b>
<br /><span style="font-weight: bold;"> resetTimer</span><b><span style="color:#663300;"><span style="font-weight: bold;">();</span>
<br /><span style="font-weight: bold;"> } </span>
<br />
<br /> }
<br />}</span></b></pre>
<br />Prima di tutto vi spiego la logica che vogliamo seguire.
<br />Definiamo che esiste un tempo minimo e un tempo massimo entro il quale creiamo una nuova astronave.
<br />Generiamo un numero casuale <pre><span style="font-weight: bold;">nextSpawn</span></pre> compreso tra questi due parametri, e ad ogni loop di gioco sottraiamo da questo numero il tempo trascorso dal ciclo successivo.
<br />Quendo il numero nextSpawn sarà minore di 0, creiamo una nuova astronave e resettiamo nextSpawn ripescando un numero casuale tra i paramentri sopra... e così via.
<br />
<br />In testa, come variabili di classe settiamo i parametri
<br /><pre><i><span style="color:#999999;"><span style="font-weight: bold;"> //tempi di attesa minimi e massimi per lo spawn dei nemici</span>
<br /></span></i><span style="font-weight: bold;color:#ff6633;" > int</span><span style="font-weight: bold;"> minEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#999900;" > 100</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><i style="font-weight: bold;"><span style="color:#999999;">//Millisecondi
<br /></span></i><span style="font-weight: bold;color:#ff6633;" > int</span><span style="font-weight: bold;"> maxEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#999900;" > 600</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><i style="font-weight: bold;"><span style="color:#999999;">//Millisecondi
<br /></span></i><span style="font-weight: bold;color:#ff6633;" > int</span><span style="font-weight: bold;"> nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> =</span></b><span style="font-weight: bold;color:#999900;" > 0</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><span style="color:#990000;">
<br />
<br /></span></pre> Che rappresentano il tempo minimo e il tempo massimo di spawn dei nemici e inizializiamo nextSpawn.
<br />
<br />Nella <span style="font-weight: bold;">initialize</span> lanciamo la funzione <span style="font-weight: bold;">resetTimer</span> che come vedete si occupa di trovare un numero casuale utilizzando l'oggetto <span style="font-weight: bold;">rnd</span> che abbiamo creato in game1.cs. Utilizza la funzione
<br /><pre><span style="font-weight: bold;">nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> = ((</span></b><span style="font-weight: bold;">Game1</span><b style="font-weight: bold;"><span style="color:#663300;">)</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">).</span></b><span style="font-weight: bold;">rnd</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Next</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">minEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;">,</span></b><span style="font-weight: bold;"> maxEnemySpawn</span><b style="font-weight: bold;"><span style="color:#663300;">); </span></b></pre> e prende i due parametri min e max come estremi del range entro il quale pescare il numero casuale.
<br />Nella <span style="font-weight: bold;">Update</span> grazie all'oggetto <span style="font-weight: bold;">gameTime</span> (finalmente ho un esempio di utilizzo per questo valore ) sottraiamo il tempo trascorso dal precedente ciclo a nextSpawn attuale, se nextSpawn è sceso sotto zero, lanciamo la funzione <span style="font-weight: bold;">spawnEnemy</span>.
<br /><pre><i><span style="color:#999999;"><span style="font-weight: bold;"> //Sotraggo il tempo passato dallo spawn time</span>
<br /></span></i><span style="font-weight: bold;"> nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> -=</span></b><span style="font-weight: bold;"> gameTime</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">ElapsedGameTime</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Milliseconds</span><b style="font-weight: bold;"><span style="color:#663300;">;</span></b><i style="font-weight: bold;"><span style="color:#999999;">
<br /> //Se lo spawn time è sceso sotto zero, genero il nuovo nemico
<br /></span></i><span style="font-weight: bold;color:#ff0000;" > if</span><b style="font-weight: bold;"><span style="color:#663300;"> (</span></b><span style="font-weight: bold;">nextSpawn</span><b style="font-weight: bold;"><span style="color:#663300;"> <</span></b><span style="font-weight: bold;color:#999900;" > 0</span><b style="font-weight: bold;"><span style="color:#663300;">) {</span></b>
<br /><span style="font-weight: bold;"> spawnEnemy</span><b style="font-weight: bold;"><span style="color:#663300;">();
<br /> }</span></b><i><span style="color:#999999;">
<br /></span></i></pre> Per quanto riguarda la <span style="font-weight: bold;">spawnEnemy </span>genera una posizione e una velocità casuale, utilizzando sempre l'oggetto <span style="font-weight: bold;">rnd </span>
<br />a questo punto in base alla velocità generà un oggetto AutoSprite con due differenti texture. Se la velocità è superiore a 5 genera Cylone minacciosissimo :P e più difficile da schivare. In entrambi i casi aggiunge l'astronave alla lista di Sprite della spriteManager.
<br />
<br />Un'ultima nota, dato che a questo punto si genereranno centinaia di astronavi, è bene occuparsi anche della memoria e fare in modo che quando le astronavi lasciano l'area di gioco, queste vengano cancellate dalla lista di sprite dato che sarebbe inutile continuare a occuparsi della loro posizione e fare check di collisioni! Sempre nella <span style="font-weight: bold;">update</span> trovate questo codice utile allo scopo sopra descritto:
<br /><pre><span style="color:#ff0000;"><span style="font-weight: bold;"> if</span></span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">s</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">OutOfView</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">Game</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">Window</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">ClientBounds</span><b style="font-weight: bold;"><span style="color:#663300;">)){</span></b><span style="font-weight: bold;"> </span>
<br /><span style="font-weight: bold;"> spriteList</span><b style="font-weight: bold;"><span style="color:#663300;">.</span></b><span style="font-weight: bold;">RemoveAt</span><b style="font-weight: bold;"><span style="color:#663300;">(</span></b><span style="font-weight: bold;">i</span><b style="font-weight: bold;"><span style="color:#663300;">);
<br /> --</span></b><span style="font-weight: bold;">i</span><b><span style="color:#663300;"><span style="font-weight: bold;">;</span>
<br /><span style="font-weight: bold;"> }</span></span></b></pre> la funzione OutOfView va inserita a fondo della classe sprite.cs eccola qui...
<br /><pre><i><span style="color:#999999;"> //lo sprite è nella finestra?
<br /></span></i><span style="color:#990000;"> public</span><span style="color:#ff6633;"> bool</span> OutOfView<b><span style="color:#663300;">(</span></b>Rectangle myRect<b><span style="color:#663300;">){</span></b><span style="color:#ff0000;">
<br /> if</span><b><span style="color:#663300;"> (</span></b>position<b><span style="color:#663300;">.</span></b>X<b><span style="color:#663300;"> <</span></b><span style="color:#999900;"> 0</span><b><span style="color:#663300;"> ||</span></b>
<br /> position<b><span style="color:#663300;">.</span></b>X<b><span style="color:#663300;"> ></span></b> myRect<b><span style="color:#663300;">.</span></b>Width<b><span style="color:#663300;"> ||</span></b>
<br /> position<b><span style="color:#663300;">.</span></b>Y<b><span style="color:#663300;"> ></span></b> myRect<b><span style="color:#663300;">.</span></b>Height<b><span style="color:#663300;">)
<br /> {</span></b><span style="color:#ff0000;">
<br /> return</span><b><span style="color:#000000;"> true</span></b><b><span style="color:#663300;">;
<br /> }</span></b><span style="color:#ff0000;">
<br /> else return</span><b><span style="color:#000000;"> false</span></b><b><span style="color:#663300;">;
<br /> }</span></b></pre>
<br />
<br />Signori... anche questa volta ci siamo riusciti... abbiamo finito e il nostro gioco inizia a prendere forma.
<br />
<br /><span style="font-weight: bold;">Codici Sorgenti Finali:</span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/5.generatore.zip">5.generatore.zip</a>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com8tag:blogger.com,1999:blog-1511468527759599388.post-8913271024846296422009-03-12T13:41:00.000-07:002011-10-05T00:47:03.537-07:007) Xna Videogame Tutorial: Testo e CollisioniQuesta settimana veramente a bomba.... 3 articoletti in due sere.. e se non sono distrutto dopo ne scrivo un altro! Tutto questo perchè settimana prossima non potrò scrivere e dato che inizio a vedere che qualche lettore mi fa spesso visita... cerco di non farlo scappare dando un pò di carne frescaaaaaaaaaaaaa ceh lo tenga occupato per un pò di giorni -.-
<br />
<br />Ehm....dicevo......
<br />
<br />In questo post tratterò due argomenti assolutamente interessanti, in primo luogo vi spiegherò come <span style="font-weight: bold;">visualizzare delle stringhe di testo</span>. Dunque utilizzeremo queste stringhe per tenere traccia dei punti vita del giocatore che diminuiranno se la nostra astronave <span style="font-weight: bold;">colliderà</span> contro una delle astronavi generate e "guidate" dal computer.
<br />Potete partire dal codice dell'articolo precedente e come sempre trovate i sorgenti finali a fondo post.
<br />
<br /><span style="font-weight: bold;">Anteprima Video</span>
<br /><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/41kcHgdZeiE&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/41kcHgdZeiE&hl=it&fs=1&rel=0&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>
<br />
<br />Andiamo per gradi. Il primo passo è l'inserimento nei nostri Contents di un elemento chiamato <span style="font-weight: bold;">spriteFont</span>, che non è nient'altro che un XML con informazioni riguardanti un tipo di Font.
<br />Anche in questo caso il buon Team di XNA è venuto incontro alle nostre esigenze, per inserire questo contenuto fate click sulla voce Content (nel frame di sinistra) quindi Add->new Item e scegliete SpriteFont, date un nome (io l'ho chiamato Arial) confermate e lo troverete magicamente disponibile tra i nostri contenuti (non spaventatevi se non vedete icone particolari... a me appare l'icona di undefined file..) .
<br />Ora cliccate due volte sul file creato e si aprirà un bellissimo XML... arrivate fino alla riga con il tag : <fontname> e scrivete Arial tra i tag come riportato qui sotto.
<br /> <span style="font-weight: bold;"><fontname>Arial</fontname></span>
<br />In questo modo abbiamo creato un riferimento al font Arial utilizzabile tramite XNA.
<br />
<br />Ora vediamo come stamparedelle stringhe a monitor, copio qui sotto il codice del file Game1.cs
<br />modificato per le nostre esigenze, analizziamolo:
<br />
<br /><span style="font-weight: bold;">GAME1</span>
<br />
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Audio<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GamerServices<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Media<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Net<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Storage<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />namespace</span> input<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br /> public class</span> Game1<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Game<b><span style="color: rgb(102, 51, 0);">
<br /> {</span></b>
<br /> GraphicsDeviceManager graphics<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(255, 102, 51);">
<br />
<br /> int</span> life<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">//Vite del giocatore
<br /></span></i> SpriteFont gui_life<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">//GUI
<br /></span></i><span style="color: rgb(153, 0, 0);">
<br /> public</span> Game1<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> graphics<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> GraphicsDeviceManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>RootDirectory<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Content"</span><b><span style="color: rgb(102, 51, 0);">;
<br />
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> SpriteManager spritemanager<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>spritemanager<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> life<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 153, 0);"> 100</span><b><span style="color: rgb(102, 51, 0);">;</span></b>
<br />
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // Create a new SpriteBatch, which can be used to draw textures.
<br /></span></i> spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Carichiamo il font!
<br /></span></i> gui_life<b><span style="color: rgb(102, 51, 0);"> =</span></b> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>SpriteFont<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"Arial"</span><b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> UnloadContent<b><span style="color: rgb(102, 51, 0);">()
<br /> {
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // Allows the game to exit
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>GamePad<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">(</span></b>PlayerIndex<b><span style="color: rgb(102, 51, 0);">.</span></b>One<b><span style="color: rgb(102, 51, 0);">).</span></b>Buttons<b><span style="color: rgb(102, 51, 0);">.</span></b>Back<b><span style="color: rgb(102, 51, 0);"> ==</span></b> ButtonState<b><span style="color: rgb(102, 51, 0);">.</span></b>Pressed<b><span style="color: rgb(102, 51, 0);">)</span></b><span style="color: rgb(153, 0, 0);">
<br /> this</span><b><span style="color: rgb(102, 51, 0);">.</span></b>Exit<b><span style="color: rgb(102, 51, 0);">();</span></b>
<br />
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> GraphicsDevice<b><span style="color: rgb(102, 51, 0);">.</span></b>Clear<b><span style="color: rgb(102, 51, 0);">(</span></b>Color<b><span style="color: rgb(102, 51, 0);">.</span></b>CornflowerBlue<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Begin<b><span style="color: rgb(102, 51, 0);">();</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawString<b><span style="color: rgb(102, 51, 0);">(</span></b>gui_life<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(0, 153, 0);"> "LIFE: "</span><b><span style="color: rgb(102, 51, 0);"> +</span></b> life<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">10</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 10</span><b><span style="color: rgb(102, 51, 0);">),</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>White<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">,</span></b> Vector2<b><span style="color: rgb(102, 51, 0);">.</span></b>Zero<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">,</span></b>SpriteEffects<b><span style="color: rgb(102, 51, 0);">.</span></b>None<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>End<b><span style="color: rgb(102, 51, 0);">();</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> // TODO: Add your drawing code here
<br /></span></i>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Gestisce le vite del player, se arrivano a zero esce
<br /></span></i><span style="color: rgb(153, 0, 0);"> public</span><span style="color: rgb(255, 102, 51);"> int</span> Life<b><span style="color: rgb(102, 51, 0);"> {</span></b>
<br /> get<b><span style="color: rgb(102, 51, 0);"> {</span></b><span style="color: rgb(255, 0, 0);"> return</span> life<b><span style="color: rgb(102, 51, 0);">; }</span></b>
<br /> set<b><span style="color: rgb(102, 51, 0);"> {</span></b>
<br /> life<b><span style="color: rgb(102, 51, 0);"> =</span></b> value<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(255, 0, 0);">
<br /> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>life<b><span style="color: rgb(102, 51, 0);"> ==</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> Exit<b><span style="color: rgb(102, 51, 0);">();
<br /> }
<br /> }
<br /> }
<br />
<br /> }
<br />}</span></b></pre>
<br />
<br />Prima di tutto noterete che ho agigunto <span style="font-weight: bold;">due variabili di classe, </span>un intero e un oggetto SpriteFont che servirà appunto per stampare la nostra stringa:
<br /><pre><span style="color: rgb(255, 102, 51);"> int</span> life<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">//Vite del giocatore
<br /></span></i> SpriteFont gui_life<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">//GUI </span></i></pre> Il secondo Step lo vediamo nella <span style="font-weight: bold;">initialize</span> dove settiamo la vita iniziale a 100, mentre nella Update carichiamo il font in gui_life
<br /><pre><i><span style="color: rgb(153, 153, 153);"> //Carichiamo il font!
<br /></span></i> gui_life<b><span style="color: rgb(102, 51, 0);"> =</span></b> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>SpriteFont<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"Arial"</span><b><span style="color: rgb(102, 51, 0);">);</span></b></pre>
<br />
<br />Nella <span style="font-weight: bold;">Draw</span> utilizziamo uno SpriteBatch per stampare la stringa
<br /><pre>spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawString<b><span style="color: rgb(102, 51, 0);">(</span></b>gui_life<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(0, 153, 0);"> "LIFE: "</span><b><span style="color: rgb(102, 51, 0);"> +</span></b> life<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 153, 0);">10</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 153, 0);"> 10</span><b><span style="color: rgb(102, 51, 0);">),</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>White<b><span style="color: rgb(102, 51, 0);">);
<br />
<br /></span></b><span style="color: rgb(102, 51, 0);font-size:100%;" ></span><b><span style="color: rgb(102, 51, 0);">
<br /></span></b></pre> Per la descrizione dei parametri di questa funzione vi rimando alla <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritebatch.drawstring.aspx">definizione della funzione</a>, in breve vi dico che il primo parametro identifica lo spritefont da utilizzare (il nostro Arial di prima), il secondo paramentro indica cosa stampare, il terzo da un'indicazione di posizione della stringa e infine definiamo il colore con il quale stampare.
<br />Tanto che siete su questo codice, date un'occhiata alla definizione di <span style="font-weight: bold;">Life</span> , tramite i paramtri set e get restituisce il valore di life .. e nel caso in cui il valore sia uguale a zero butta fuori dal programma (una sorta di grezzo gameover..) bene...a breve vedremo dove utilizzare questa definizione.
<br />
<br />Compilando dovreste già essere in grado di vedere il testo in alto a destra :D
<br />
<br />Ora passiamo al discorso collisioni!
<br />Quello che vogliamo è far si che quando la nostra astronave collide contro una astronave generata, quest'ultima scompaia e i nostri punti vita diminuiscano.
<br />Per far si che questo avvenga dobbiamo mettere mano unicamente allo spritemanager:
<br />Ecco qui il nuovo codice per intero
<br />
<br /><span style="font-weight: bold;">SPRITEMANAGER</span>
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Audio<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GamerServices<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Media<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Net<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Storage<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />
<br />namespace</span> input<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><i><span style="color: rgb(153, 153, 153);">
<br /></span></i><span style="color: rgb(153, 0, 0);"> public class</span> SpriteManager<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>DrawableGameComponent<b><span style="color: rgb(102, 51, 0);">
<br /> {</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> List<b><span style="color: rgb(102, 51, 0);"><</span></b>Sprite<b><span style="color: rgb(102, 51, 0);">></span></b> spriteList<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> List<b><span style="color: rgb(102, 51, 0);"><</span></b>Sprite<b><span style="color: rgb(102, 51, 0);">>();</span></b>
<br />
<br /> <b style="font-weight: bold;">ControlledSprite player<span style="color: rgb(102, 51, 0);">;</span></b>
<br />
<br /> Texture2D tex1<b><span style="color: rgb(102, 51, 0);">,</span></b> tex2<b><span style="color: rgb(102, 51, 0);">,</span></b> texp<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Vector2 pos1<b><span style="color: rgb(102, 51, 0);">,</span></b> pos2<b><span style="color: rgb(102, 51, 0);">,</span></b> posp<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Vector2 spd1<b><span style="color: rgb(102, 51, 0);">,</span></b> spd2<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> SpriteManager<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br /> {
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> // TODO: Add your initialization code here
<br /></span></i> pos1<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">10.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);"> 1.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> pos2<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">30.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);"> 2.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Aggiugngo una posizione iniziale per il giocatore... altrimenti collide da subito con gli sprite
<br /></span></i> <b style="font-weight: bold;">posp<span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);">500.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);"> 400.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spd1<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(153, 102, 0);">2.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">1.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spd2<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">0.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);"> 2.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> tex1<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"enemy"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> tex2<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"enemy2"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> texp<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"spaceship"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br /><span style="font-weight: bold;"> //ho estratto il giocatore dalla lista di sprite</span>
<br /><span style="font-weight: bold;"> //spriteList.Add(new ControlledSprite(texp, new Vector2(0.0f, 0.0f)));</span>
<br /></span></i><span style="font-weight: bold;"> player</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> ControlledSprite</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">texp</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> posp</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> spd1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex1<b><span style="color: rgb(102, 51, 0);">,</span></b>pos1<b><span style="color: rgb(102, 51, 0);">,</span></b>spd1<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex1<b><span style="color: rgb(102, 51, 0);">,</span></b> pos2<b><span style="color: rgb(102, 51, 0);">,</span></b> spd2<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex2<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">300.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">0.0f</span><b><span style="color: rgb(102, 51, 0);">),</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(153, 102, 0);">1.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">3.0f</span><b><span style="color: rgb(102, 51, 0);">)));</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>LoadContent<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Aggiorno il giocatore
<br /></span></i> player<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Aggiorno tutti gli elementi della lista, al posto del foreach usiamo un for
<br /></span></i><span style="color: rgb(255, 0, 0);"> <span style="font-weight: bold;">for</span></span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> (</span></b><span style="font-weight: bold; color: rgb(255, 102, 51);">int</span><span style="font-weight: bold;"> i</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="font-weight: bold;"> i</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> <</span></b><span style="font-weight: bold;"> spriteList</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Count</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="font-weight: bold;"> i</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">++) {</span></b>
<br /> Sprite s<b><span style="color: rgb(102, 51, 0);"> =</span></b> spriteList<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">];</span></b>
<br />
<br /> s<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Controllo se uno degli sprite nemici collide contro il giocatore
<br /></span></i><span style="color: rgb(255, 0, 0);"> <span style="font-weight: bold;">if</span></span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> (</span></b><span style="font-weight: bold;">s</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">collisionRect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Intersects</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">player</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">collisionRect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">)) {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Tolgo una vita al player
<br /></span></i><b><span style="color: rgb(102, 51, 0);"> --((</span></b>Game1<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">).</span></b>Life<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>RemoveAt<b><span style="color: rgb(102, 51, 0);">(</span></b>i<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br /> }</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Begin<b><span style="color: rgb(102, 51, 0);">();</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Disegno il giocatore
<br /></span></i> <b style="font-weight: bold;">player<span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Draw</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">gameTime</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;">spriteBatch</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Disegno tutti gli elementi della lista
<br /></span></i> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>Sprite s in spriteList<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> s<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">,</span></b>spriteBatch<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>End<b><span style="color: rgb(102, 51, 0);">();
<br /> }
<br />
<br /> }
<br />}</span></b></pre>
<br />Bene, ho un pò di novità da farvi notare (le ho evidenziate sopra in <span style="font-weight: bold;">Grassetto</span>)
<br />Prima di tutto ho <span style="font-weight: bold;">estrapolato il giocatore dalla lista di sprite</span> dello spritemanager, preferisco gestirlo a parte (questo tornerà utilie quando dovremo fare il chekc della lista sprite per vedere se ci sono collisioni).
<br />In secondo luogo ho modificato la sua posizione di partenza nella <span style="font-weight: bold;">initialize</span>
<br /><pre><b style="font-weight: bold;">posp<span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);">500.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);"> 400.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b></pre> Nella load content ho commentato la riga dove inserivo il player nella lista di sprite e l'ho sostituita con una nuova che associa all'oggetto "Player", definito in testa alla classe, il nuovo oggetto ControlledSprite
<br /><pre><i><span style="color: rgb(153, 153, 153);"><span style="font-weight: bold;">//spriteList.Add(new ControlledSprite(texp, new Vector2(0.0f, 0.0f)));</span>
<br /></span></i><span style="font-weight: bold;">player</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> ControlledSprite</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">texp</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> posp</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold;"> spd1</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b></pre> Nella update sostituiamo il precedente foreach che percorreva la lista con un for (sarà più comodo per fare riferimento alla posizione degli elementi nella lista)
<br /><pre><span style="color: rgb(255, 0, 0);"><span style="font-weight: bold;">for</span></span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> (</span></b><span style="font-weight: bold; color: rgb(255, 102, 51);">int</span><span style="font-weight: bold;"> i</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold; color: rgb(153, 153, 0);"> 0</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="font-weight: bold;"> i</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> <</span></b><span style="font-weight: bold;"> spriteList</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Count</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="font-weight: bold;"> i</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">++) {</span></b>
<br />Sprite s<b><span style="color: rgb(102, 51, 0);"> =</span></b> spriteList<b><span style="color: rgb(102, 51, 0);">[</span></b>i<b><span style="color: rgb(102, 51, 0);">];......</span></b></pre> All'interno del for a questo punto troverete il blocco che si occupa di verificare se uno degli sprite collide con il player ( che abbiamo appositamente estrapolato da questa lista)
<br />
<br /><pre><i><span style="color: rgb(153, 153, 153);"> //Controllo se uno degli sprite nemici collide contro il giocatore
<br /></span></i><span style="color: rgb(255, 0, 0);"> <span style="font-weight: bold;">if</span></span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> (</span></b><span style="font-weight: bold;">s</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">collisionRect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Intersects</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">player</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">collisionRect</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">)) {</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Tolgo una vita al player
<br /></span></i><b><span style="color: rgb(102, 51, 0);"> --((</span></b>Game1<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">).</span></b>Life<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>RemoveAt<b><span style="color: rgb(102, 51, 0);">(</span></b>i<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br /></span></b></pre> Avevamo definito tramite collisionRect nella classe Sprite.cs (riporta semplicemente la posizione occupata dallo sprite), e utilizzando la funzione intersect di XNA controlleremo se avviene l'intersezione con il nostro player... in tal caso facciamo un bel casting (almeno credo)
<br /><pre><b><span style="color: rgb(102, 51, 0);">--((</span></b>Game1<b><span style="color: rgb(102, 51, 0);">)</span></b>Game<b><span style="color: rgb(102, 51, 0);">).</span></b>Life<b><span style="color: rgb(102, 51, 0);">;</span></b></pre> e raggiungiamo la <span style="font-weight: bold;">Life</span> che vi ho mostrato prima e sfruttando la proprietà set decrementiamo punti dall'intero life.
<br />a quest opunto rimuoviamo l'elemento con il quale è avvenuta la collisione dalla lista di sprite da stampare.
<br />
<br />Signori e signori... abbiamo già finito...
<br />potrete vedere che muovendo la vostra astronave contro uno sprite questo sparirà e il vostro punteggio vita si abbasserà!
<br />
<br /><span style="font-weight: bold;">Codici sorgenti finali</span>:
<br /><a href="http://www.thinkandbuild.it/imparandoxna/4.collisioni.zip">4.collisioni.zip</a></fontname>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com4tag:blogger.com,1999:blog-1511468527759599388.post-76559569942762884732009-03-12T11:59:00.000-07:002011-10-05T00:47:27.949-07:006) XNA videogame tutorial: Keyboard Input<div style="text-align: left;">Nello scorso post vi ho raccontato come utilizzare i GameComponents e come scrivere una classe per gestire degli oggetti sprites.
<br />Oggi invece vi mostrerò come pilotare un'astronave attraverso la tastiera!
<br />Come sorgente iniziale potete utilizzare quello della lezione precedente, alla quale aggiungeremo una classe ( a fondo lezione trovere il sorgente finale) .
<br />Cercherò di non tirarla alle lunghe questa volta perchè l'argomento è veramente semplice, come già detto sopra lo scopo è quello di far si che tramite l'utilizzo della tastiera si possa decidere il posizionamento della nostra astronave, se ricordate abbiamo usato una classe astratta "<span style="font-weight: bold;">Sprite</span>" che poi abbiamo derivato con una classe "<span style="font-weight: bold;">AutoSprite</span>" che permetteva alle astronavi di muoversi autonomamente. Oggi creeremo la classe "<span style="font-weight: bold;">Controlled Sprite</span>" controllata dall'utente, naturalmente derivando la classe Sprite come per AutoSprite.
<br />
<br /><span style="font-weight: bold;">Video Anteprima</span>
<br /><object width="480" height="385"><param name="movie" value="http://www.youtube.com/v/ulcyKzNTpZM&hl=it&fs=1&color1=0x234900&color2=0x4e9e00"></param><param name="allowFullScreen" value="true"></param><param name="allowscriptaccess" value="always"></param><embed src="http://www.youtube.com/v/ulcyKzNTpZM&hl=it&fs=1&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="480" height="385"></embed></object>
<br />
<br />
<br />La classe si dovrà in poche parole occupare di intercettare il nostro input (useremo le frecce direzionali) e in base a questo modificare i parametri X e Y del vettore posizione dell'astronave.
<br /><span style="font-weight: bold;"></span>Ecco il codice completo della nuova classe e di seguito la spiegazione:
<br />
<br /></div><div style="text-align: left;"><span style="font-weight: bold;">CONTROLLED SPRITE </span>
<br /></div><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />namespace</span> input<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br />class</span> ControlledSprite<b><span style="color: rgb(102, 51, 0);"> :</span></b> Sprite<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);"></span><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> ControlledSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>Texture2D new_texture<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector2 new_position<b><span style="color: rgb(102, 51, 0);">,</span></b>Vector2 new_speed<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>new_texture<b><span style="color: rgb(102, 51, 0);">,</span></b> new_position<b><span style="color: rgb(102, 51, 0);">,</span></b> new_speed<b><span style="color: rgb(102, 51, 0);">)
<br /> {
<br />
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> position<b><span style="color: rgb(102, 51, 0);"> +=</span></b> direction<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><i><span style="color: rgb(153, 153, 153);">
<br />
<br /> //Controlla gli input da tastiera (volendo qui si possono aggiungere
<br /> //altri device, come mouse e pad)
<br /> //E restituisce info sulla direzione
<br /></span></i><span style="color: rgb(153, 0, 0);"> public</span> Vector2 direction<b><span style="color: rgb(102, 51, 0);"> {</span></b>
<br /> get<b><span style="color: rgb(102, 51, 0);"> {</span></b>
<br /> Vector2 inputDirection<b><span style="color: rgb(102, 51, 0);"> =</span></b> Vector2<b><span style="color: rgb(102, 51, 0);">.</span></b>Zero<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Movimento destra
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>Keyboard<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">().</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Left<b><span style="color: rgb(102, 51, 0);">)) {</span></b>
<br /> inputDirection<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);"> -=</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Movimento sinistra
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>Keyboard<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">().</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Right<b><span style="color: rgb(102, 51, 0);">))
<br /> {</span></b>
<br /> inputDirection<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);"> +=</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Movimento su
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>Keyboard<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">().</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Up<b><span style="color: rgb(102, 51, 0);">))
<br /> {</span></b>
<br /> inputDirection<b><span style="color: rgb(102, 51, 0);">.</span></b>Y<b><span style="color: rgb(102, 51, 0);"> -=</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Movimento giù
<br /></span></i><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>Keyboard<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">().</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Down<b><span style="color: rgb(102, 51, 0);">))
<br /> {</span></b>
<br /> inputDirection<b><span style="color: rgb(102, 51, 0);">.</span></b>Y<b><span style="color: rgb(102, 51, 0);"> +=</span></b><span style="color: rgb(153, 153, 0);"> 1</span><b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><span style="color: rgb(255, 0, 0);">
<br />
<br /> return</span> inputDirection<b><span style="color: rgb(102, 51, 0);"> *</span></b> speed<b><span style="color: rgb(102, 51, 0);">;
<br /> }
<br /> }
<br />}
<br />}</span></b>
<br />
<br />
<br /></pre><div style="text-align: left;">(Vi ricordo che il namespace che vedete qui dipende da come ho chiamato il mio progetto.. per evitare problemi utilizzate il vostro namespace (oppure partite dal codice che vi allego sotto :P )
<br />Vediamo come viene creata questa classe..... Prima di tutto nella definizione di classe Ereditate le info della classe Sprite con "<span style="font-weight: bold;">: Sprite</span>"
<br />Il <span style="font-weight: bold;">costruttore</span> è identico a quello proposto nella Sprite e fino a qui niente di nuovo.... Ora entriamo nella <span style="font-weight: bold;">Update</span>, qui andiamo a modificare il valore di position utilizzando la proprietà <span style="font-weight: bold;">direction</span> definita sotto, notate che tramite <span style="font-weight: bold;">get</span> andiamo a chiamare una funziona che vi suonerà nuova :
<br /><pre>Keyboard<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">().</span></b>IsKeyDown<b><span style="color: rgb(102, 51, 0);">(</span></b>Keys<b><span style="color: rgb(102, 51, 0);">.</span></b>Left<b><span style="color: rgb(102, 51, 0);">)</span></b></pre> <div style="text-align: left;">Non stiamo facendo altro che controllare se la freccia sinistra è premuta...sfruttando la funzione GetState dell'oggetto Keyboard, appositamente creato per XNA :D. Notate ceh in testa alla classe abbiamo definito che utilizzeremo il namespace input di XNA:
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /></span></pre>Questo oggetto ha parecchie funzioni interessanti (utili per gestire altri device come Pad e mouse) vi rimando a <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.input.aspx">questo link</a> per scoprirle meglio.
<br />
<br />Tornando alla nostra funzione update noterete che verifichiamo con un blocco di IF se una delle frecce è premuta, in tal caso decrementiamo o incrementiamo le chiavi X o Y dell'oggetto inputDirection.
<br />E come ultimo passaggio moltiplichiamo il valore per la Velocità dell'astronave, il valore verrà dunque sommato all'attuale position e quindi alla chiamata della Draw (che se vi ricordate, parte dal foreach dentro la Draw dello spritemanager..... scrorre tutti gli elementi della lista sprite e chiama per questi elementi le rispettive funzioni Draw) .
<br />In questo caso come potete notare non abbiamo una Draw, quindi utilizzeremo quella della classe Padre (Sprite.cs) che va più che bene per i nostri scopi.
<br />
<br /><span style="font-weight: bold;">Aggiungiamo l'astronave controllabile nello spritemanager</span>:
<br />Nella classe SpriteManager.cs aggiungete le informazioni che ho inserito qui in neretto nella funzione LoadContent.
<br /><pre><span style="color: rgb(153, 0, 0);"> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> tex1<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"enemy"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> tex2<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"enemy2"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /><span style="font-weight: bold;"> texp</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"> =</span></b><span style="font-weight: bold;"> Game</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Content</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Load</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);"><</span></b><span style="font-weight: bold;">Texture2D</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">>(</span></b><span style="font-weight: bold; color: rgb(0, 153, 0);">"spaceship"</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /><span style="font-weight: bold;"> spriteList</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Add</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">new</span><span style="font-weight: bold;"> ControlledSprite</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold;">texp</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);"> new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);">0.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);"> 0.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">),</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">new</span><span style="font-weight: bold;"> Vector2</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">(</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);">3.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">,</span></b><span style="font-weight: bold; color: rgb(153, 102, 0);">3.0f</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">)));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex1<b><span style="color: rgb(102, 51, 0);">,</span></b>pos1<b><span style="color: rgb(102, 51, 0);">,</span></b>spd1<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex1<b><span style="color: rgb(102, 51, 0);">,</span></b> pos2<b><span style="color: rgb(102, 51, 0);">,</span></b> spd2<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex2<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">300.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">0.0f</span><b><span style="color: rgb(102, 51, 0);">),</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(153, 102, 0);">1.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">3.0f</span><b><span style="color: rgb(102, 51, 0);">)));</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>LoadContent<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b></pre><div style="text-align: left;">Come potete notare andiamo semplicemente ad aggiungere un elemento alla lista SpriteList (e nel caso non ci fosse già creiamo una texture per questo elemento... attenzione! ricordatevi di aggiungere la texture ai contenuti Add->existing Item .... la vostra texture) .
<br />
<br />Vi faccio notare che la lista spriteList è stata definita come :
<br />List<sprite> spriteList = new List<sprite>()<span style="font-family:monospace;">;
<br />
<br /></span>Quindi una lista di oggetti Sprite.... eppure noi nella lista abbiamo aggiunto oggetti ControlledSprite e AutoSprite....l'operazione è comunque valida proprio perchè questi oggetti sono specializzazioni della classe Sprite. Se volete avere qualche info in più sulla sintassi sopra leggete questo articolo<a href="http://msdn.microsoft.com/it-it/library/0x6a29h6.aspx"> sulle classi generiche in C#.</a><span style="font-family:monospace;">
<br />
<br /></span></sprite></sprite><sprite><sprite><div style="text-align: left;"><div style="text-align: left;"><span style="display: block;" id="formatbar_Buttons"><span class="down" style="display: block;" id="formatbar_JustifyLeft" title="Allinea a sinistra" onmouseover="ButtonHoverOn(this);" onmouseout="ButtonHoverOff(this);" onmouseup="" onmousedown="CheckFormatting(event);FormatbarButton('richeditorframe', this, 10);ButtonMouseDown(this);"><img src="http://www.blogger.com/img/blank.gif" alt="Allinea a sinistra" class="gl_align_left" border="0" /></span></span><span>A questo punto compilando, dovreste vedere una nuova astronave in alto a sinistra, ferma immobile...</span>
<br /></div><span>bhe muovetela con la vostra tastiera! :D </span>
<br /><span></span></div><span>
<br /><span style="font-weight: bold;">Codici Sorgenti Finali:</span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/3.input.zip">3.input.zip</a>
<br />
<br />
<br /></span></sprite></sprite></div></div></div><pre>
<br />
<br /></pre>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com1tag:blogger.com,1999:blog-1511468527759599388.post-34800973607294453802009-03-11T13:05:00.000-07:002011-10-05T00:48:01.849-07:005) Xna Videogame Tutorial : I GameComponentsCiao a tutti!
<br />Ecco la 2° parte di questa piccola guida per la creazione del nostro primo semplice videogame.
<br />Questa settimana ci do un pò dentro cercando di scrivere il più possibile, dato che la prossima settimana con molta probabilità sarò fermissimo -.-
<br />
<br />Allora, nello scorso post abbiamo visto come disegnare uno sprite e come animarlo nello spazio della finestra di gioco.
<br />Come avrete visto, ci sono alcuni passaggi che risulterebbero essere un pò ripetitivi nel caso in cui volessimo gestire più di una o due astronavi.
<br />Le chiamate delle funzioni spritebatch.draw e i vari aggiornamenti di posizione dell'Update andrebbero ripetuti per ogni astronave...il che sarebbe decisamente poco elegante e senza dubbio scomodo!
<br />
<br />Lo scopo di questa lezione è sfruttare questa problematica per presentarvi i game components e fare un piccolo passaggio sulla programmazione ad oggetti... (non mi addentrerò nei meandri oscuri dell'OOP ma vi fornirò un paio di nozioni mano a mano che scrivo) .
<br />A chi volesse dare una ripassata veloce all'argomento OOP, consiglio di fare un saltino <a href="http://programmazione.html.it/guide/leggi/38/guida-programmazione-orientata-agli-oggetti/">qui </a>.
<br />
<br />Vi consiglio di creare un progetto nuovo, non utilizzate il precedente come punto di partenza.
<br />
<br /><span style="font-weight: bold;">Video Anteprima:</span>
<br /><object width="425" height="344"><param name="movie" value="http://www.youtube.com/v/iGrPbOle2IU&hl=it&fs=1&color1=0x234900&color2=0x4e9e00"><param name="allowFullScreen" value="true"><param name="allowscriptaccess" value="always"><embed src="http://www.youtube.com/v/iGrPbOle2IU&hl=it&fs=1&color1=0x234900&color2=0x4e9e00" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="425" height="344"></embed></object>
<br />
<br />Prima di tutto cerchiamo di trattare lo sprite come un'entità separata dal corpo del programma, rendiamolo in sostanza un OGGETTO, questo permetterà il suo semplice riutilizzo! e pulirà il nostro codice aggiungendo un pò di logica e ordine.
<br />Una volta che avremo definito al meglio l'oggetto sprite, ci occuperemo di trovare un elemento capace di gestire una lista di oggetti sprite e di inserirli nel game Loop... e indovinate un pò...per risolvere quest'ultimo problema utilizzeremo un Game Component.
<br />
<br /><span style="font-weight: bold;">Quindi gli step che seguiremo sono i seguenti:</span>
<br /><span style="font-weight: bold;">1)</span> Definizione dell'oggetto sprite e sue derivazioni
<br /><span style="font-weight: bold;">2)</span> Definizione di un gamecomponent per la gestione degli sprites (sprite manager)
<br />
<br /><span style="font-weight: bold;">Oggetto sprite</span>:
<br />Tramite l'oggetto sprite dovremo gestire tutte le funzioni e le variabili che erano associate allo sprite inserito "manualmente" nel codice precedente.
<br />Quindi ci servirà avere informazioni come Posizione, Texture, Velocità e avere dei metodi Update e Draw dedicati.
<br />Oltretutto, dato che siamo troppo avanti ( o meglio... Aaron Reed è troppo avanti :P ) , non ci limiteremo a creare una Classe Sprite, ma la creeremo come classe astratta e andremo a definire delle classi derivati dalla Sprite.
<br />
<br /><span style="font-size:85%;"><span style="font-weight: bold;">Ripasso OOP Classi astratte:</span>-------------------------------------------------
<br />Una Classe Astratta, è una classe tramite la quale "non è possibile" istanziare nessun oggetto, viene utilizzata come base per lo studio di classi specializzate che andranno ad estendere ed ereditare le informazioni presenti nella classe padre (per l'appunto la classe astratta).
<br />
<br /><span style="font-style: italic;">Esempio:</span>
<br />La classe <span style="font-style: italic;">Figura</span>, ha un metodo CalcolaArea, un metodo SettaAltezza, un metodo SettaLarghezza, un parametro larghezza e un parametro altezza.
<br />In questo esempio non avrebbe senso implementare il metodo CalcolaArea, perchè non sapremmo con quale formula calcolarla, quindi ci servirà solo come base, ricordandoci che nelle specializzazioni di questa classe dovremmo implementare una funzione Calcola</span><span style="font-size:85%;">Area che faccia l'override del metodo padre (è un concetto molto simile al concetto di implementazione di interfaccia) definiremo questa funzione come "<span style="font-weight: bold;">virtual</span>", il che ci consente di reimplementare un metodo CalcolaArea in tutte le classi derivate dalla classe Figura. (merdacc ci vorrebbe un'oretta fatta bene per</span><span style="font-size:85%;"> spiegare questi concetti... spero che vi servano almeno come ripasso... spiegarli da zero è veramente un lavoraccio).
<br />A differenza del metodo CalcolaArea, potremmo però implemetare i metodi SettaAltezza e SettaLarghezza che si occuperanno di settare i valore altezza e larghezza verficando che siano maggiori di zero.
<br />Questi metodi potrebbero a questo punto essere utilizzati dalle classi derivate senza doverne implementare una versione propria.
<br />-----------------------------------------------------------------------------------------</span>
<br />
<br />
<br /><span style="font-weight: bold;">Implementeremo questa gerarchia:</span>
<br />
<br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy5S3uGrTVf4uLtsP8kmZQe0JTNxurE8irunTHRiYcxH6XTv5Uxcq8UFOYLvG4DqAMJHDtJ8pA8xUEqJ3sX3Z4QFX1ijBu4IBrxsT1cVIbgE1TbGz_p71xzm0MeBwLJIaqy8tmbUdey44/s1600-h/sprite.jpg"><img style="cursor: pointer; width: 400px; height: 300px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiy5S3uGrTVf4uLtsP8kmZQe0JTNxurE8irunTHRiYcxH6XTv5Uxcq8UFOYLvG4DqAMJHDtJ8pA8xUEqJ3sX3Z4QFX1ijBu4IBrxsT1cVIbgE1TbGz_p71xzm0MeBwLJIaqy8tmbUdey44/s400/sprite.jpg" alt="" id="BLOGGER_PHOTO_ID_5312037190435641794" border="0" /></a>
<br /><span style="font-weight: bold;">Sprite (Sprite.cs):</span>
<br />La classe astratta dalla quale erediteremo funzioni e che useremo come interfaccia.
<br />
<br /><span style="font-weight: bold;">Automa (AutoSprite.cs):</span>
<br />Una classe che permetterà agli sprite di muoversi autonomamente
<br />
<br /><span style="font-weight: bold;">Guidato (ControlledSprite.cs):</span>
<br />La classe che produrrà l'oggetto sprite pilotato dall'utente tramite tastiera (Nella prossima lezione)
<br />
<br />
<br />Qui sotto riporto il codice della classe SPRITE:
<br />(per aggiungere una classe al progetto, andate nella barra di destra di visual c# cliccate con il destro in un'area libera e Add->New Item ----> Visual c# Item -> e aggiungete un'elemento Class compilando il form
<br />
<br /><span style="font-weight: bold;">SPRITE--------------------------------</span>
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /><span style="font-weight: bold;">using</span></span><span style="font-weight: bold;"> Microsoft</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Xna</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Framework</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="font-weight: bold; color: rgb(153, 0, 0);">
<br />using</span><span style="font-weight: bold;"> Microsoft</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Xna</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Framework</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">.</span></b><span style="font-weight: bold;">Graphics</span><b style="font-weight: bold;"><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />namespace</span> sprite_manager2<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b>
<br />abstract<span style="color: rgb(153, 0, 0);"> class</span> Sprite<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br /> protected</span> Texture2D texture<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /> protected</span> Vector2 position<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /> protected</span> Vector2 speed<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /></span>
<br /><span style="color: rgb(153, 0, 0);"> public</span> Sprite<b><span style="color: rgb(102, 51, 0);">(</span></b>Texture2D new_texture<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector2 new_position<b><span style="color: rgb(102, 51, 0);">,</span></b>Vector2 new_speed<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b><span style="color: rgb(153, 0, 0);">
<br /> this</span><b><span style="color: rgb(102, 51, 0);">.</span></b>texture<b><span style="color: rgb(102, 51, 0);"> =</span></b> new_texture<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /> this</span><b><span style="color: rgb(102, 51, 0);">.</span></b>position<b><span style="color: rgb(102, 51, 0);"> =</span></b> new_position<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /> this</span><b><span style="color: rgb(102, 51, 0);">.</span></b>speed<b><span style="color: rgb(102, 51, 0);"> =</span></b> new_speed<b><span style="color: rgb(102, 51, 0);">;
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public virtual</span><span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">) {
<br />
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public virtual</span><span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">,</span></b> SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">){</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>texture<b><span style="color: rgb(102, 51, 0);">,</span></b> position<b><span style="color: rgb(102, 51, 0);">,</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>White<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> Rectangle collisionRect<b><span style="color: rgb(102, 51, 0);"> {</span></b>
<br /> get<b><span style="color: rgb(102, 51, 0);"> {</span></b><span style="color: rgb(255, 0, 0);">
<br /> return</span><span style="color: rgb(153, 0, 0);"> new</span> Rectangle<b><span style="color: rgb(102, 51, 0);">((</span></b><span style="color: rgb(255, 102, 51);">int</span><b><span style="color: rgb(102, 51, 0);">)</span></b>position<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);">, (</span></b><span style="color: rgb(255, 102, 51);">int</span><b><span style="color: rgb(102, 51, 0);">)</span></b>position<b><span style="color: rgb(102, 51, 0);">.</span></b>Y<b><span style="color: rgb(102, 51, 0);">,</span></b> texture<b><span style="color: rgb(102, 51, 0);">.</span></b>Width<b><span style="color: rgb(102, 51, 0);">,</span></b> texture<b><span style="color: rgb(102, 51, 0);">.</span></b>Height<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br /> }
<br />}
<br />}</span></b></pre>
<br />Un piccolo appunto, creando una classe base di visual c# mancheranno i vari Using dedicati a XNA... dovrete aggiungerli voi, e un'altra cosa... il namespace che vedete dipenderà da come avrete chiamato il progetto quindi non fate troppo caso ai miei...
<br />
<br />Analiziamo velocemente il codice:
<br />In testa abbiamo le <span style="font-weight: bold;">variabili di classe</span> che descrivono i parametri di nostro interesse, quindi texture, posizione e velocità.
<br />
<br />Per quanto riguarda il <span style="font-weight: bold;">costruttore</span>, imposta semplicemente le variabili di classe con quanto passato in fase di creazione dell'oggetto.
<br />
<br />L'<span style="font-weight: bold;">update</span> è una virtual (che quindi potrà essere implementata nelle classi che deriveranno dalla Sprite) senza contenuto.
<br />
<br />Nella <span style="font-weight: bold;">Draw</span>, anch'essa virtual, chiameremo la draw dell'oggetto spriteBatch che ci viene passato come parametro inviando i dati texture e posizione.
<br />
<br />In aggiunta notate la variabile <span style="font-weight: bold;">collisionRect</span> implementata tramite la proprietà get (andate <a href="http://www.docenti.org/Corsi/c/lezione9.htm">qui</a> per approffondire il d iscorso proprietà get / set, è fottutamente semplice e comodo) che restituira il rettangolo occupato dall'oggetto Sprite (come potete immaginare sarà utilissimo per calcolare le collisioni).
<br />
<br />Ok dunque abbiamo creato la nostra classe base, ora occupiamoci della prima derivazione, una classe dalla quale istanziare oggetti in grado di muoversi in maniera autonoma.
<br />
<br /><span style="font-weight: bold;">AUTOSPRITE-----------------------</span>
<br /><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Text<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>F
<br />ramework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />namespace</span> sprite_manager2<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br />class</span> AutoSprite<b><span style="color: rgb(102, 51, 0);"> :</span></b> Sprite<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b>
<br />
<br /><span style="color: rgb(153, 0, 0);"> public</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>Texture2D new_texture<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector2 new_position<b><span style="color: rgb(102, 51, 0);">,</span></b> Vector2 new_speed<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>new_texture<b><span style="color: rgb(102, 51, 0);">,</span></b>new_position<b><span style="color: rgb(102, 51, 0);">,</span></b>new_speed<b><span style="color: rgb(102, 51, 0);">)
<br /> { }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> position<b><span style="color: rgb(102, 51, 0);"> +=</span></b> speed<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }
<br />
<br />}
<br />}</span></b></pre>
<br />Per creare questa classe seguite lo stesso passaggio seguito per la Sprite.
<br />La prima cosa alla quale dovete far caso è la <span style="font-weight: bold;">definizione della classe</span>, e la sua derivazione dalla classe Sprite tramite l'operatore ":" .
<br />Il <span style="font-weight: bold;">costruttore</span> si occupa semplicemente di chiamare il costruttore padre tramite l'operatore <a href="http://msdn.microsoft.com/it-it/library/hfw7t1ce%28VS.80%29.aspx">base</a> e passando tutti i paramentri ricevuti in fase di creazione dell'oggetto.
<br />La funzione <span style="font-weight: bold;">Update</span> come noterete utilizza la parola chiave <span style="font-weight: bold;">override</span>, qualche riga sopra nell'update della sprite se vi ricordate abbiamo usato la parola virtual per definire che questo metodo potrebbe essere sovrascritto nelle classi figlie. Ed è proprio quello che abbiamo fatto nella AutoSprite definendo che nell'update modificheremo le informazioni di posizione e poi richiameremo l'update della classe padre (questa cosa non penso sia obbligatoria a dire il vero..ma vedo ceh è una pratica ripetuta in molti tutorial.. quindi la seguo da bravo caprone, ho provato a non inserire la chiamata all'update padre.. e funziona tutto correttamente).
<br />
<br /><span style="font-weight: bold;">Dove siamo ora??</span>
<br />A questo punto abbiamo creato una classe in grado di generare oggetti sprite in maniera abbastanza rapid a, saremmo già in grado di aggiungere degli sprite in game1.cs, dovremmo istanziare un'oggetto di tipo AutoSprite e nella classe update (di game1) e draw (sempre di game1 ) chiamare i metodi update e draw del nostro oggetto AutoSprite.
<br />Sincera mente salterò questo passaggio e vi porterò direttamente alla creazione di sprite tramite uno <span style="font-weight: bold;">sprite manager</span>!
<br />
<br /><span style="font-weight: bold;">Lo scopo dello sprite Manager:</span>
<br />Principalmente creeremo uno sprite manager per incapsulare la logica di creazione degli sprite in un sistema dedicato unicamente a questo scopo. Questo ci permetterà di riutilizzare lo spriteManager anche in altre occasioni e in altre nostre creazioni.
<br />Per aggiungere lo spritemanager dovremmo creare una classe derivata da un GameComponent .. anzi, a dire il vero da un DrawableGameComponent dato che dovremo sovrascrivere la funzione Draw.
<br />Quello che dovrete fare è aggiungere un nuovo file .. solito passaggio Add->new Item e questa volta scegliere XNA Game Studio come categoria e GameComponent come scelta finale. Chiamatelo SpriteManager. A questo punto avrete del codice in parte pronto, come prima modifica ricordatevi di sostituire
<br /><pre><span style="color: rgb(153, 0, 0);">public class</span> SpriteManager<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GameComponent
<br />
<br />Con
<br />
<br /><span style="color: rgb(153, 0, 0);">public class</span> SpriteManager<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span>Drawable</b>GameComponent<b><span style="color: rgb(102, 51, 0);">
<br /></span></b>
<br /></pre>
<br /><span style="font-weight: bold;">SPRITEMAN</span><span style="font-weight: bold;">AGER------------------------------------
<br /></span><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Linq<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Audio<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GamerServices<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Media<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Net<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Storage<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br />
<br />namespace</span> sprite_manager2<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b><span style="color: rgb(153, 0, 0);">
<br />public class</span> SpriteManager<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>
<br />Framework<b><span style="color: rgb(102, 51, 0);">.</span>Drawable</b>GameComponent<b><span style="color: rgb(102, 51, 0);">
<br />{</span></b>
<br /> SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> List<b><span style="color: rgb(102, 51, 0);"><</span></b>Sprite<b><span style="color: rgb(102, 51, 0);">></span></b> spriteList<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> List<b><span style="color: rgb(102, 51, 0);"><</span></b>Sprite<b><span style="color: rgb(102, 51, 0);">>();</span></b>
<br /> Texture2D tex1<b><span style="color: rgb(102, 51, 0);">,</span></b> tex2<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Vector2 pos1<b><span style="color: rgb(102, 51, 0);">,</span></b> pos2<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Vector2 spd1<b><span style="color: rgb(102, 51, 0);">,</span></b> spd2<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> SpriteManager<b><span style="color: rgb(102, 51, 0);">(</span></b>Game game<b><span style="color: rgb(102, 51, 0);">)
<br /> :</span></b> base<b><span style="color: rgb(102, 51, 0);">(</span></b>game<b><span style="color: rgb(102, 51, 0);">)
<br /> {
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> pos1<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">10.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);"> 1.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> pos2<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">30.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);"> 2.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br />
<br /> spd1<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(153, 102, 0);">2.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">1.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spd2<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">0.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);"> 2.0f</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()
<br /> {</span></b>
<br /> tex1<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"enemy"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> tex2<b><span style="color: rgb(102, 51, 0);"> =</span></b> Game<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b><span style="color: rgb(0, 153, 0);">"enemy2"</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>Game<b><span style="color: rgb(102, 51, 0);">.</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b><i><span style="color: rgb(153, 153, 153);">
<br /> //Aggiungiamo nuovi sprite----------------------
<br /></span></i> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex1<b><span style="color: rgb(102, 51, 0);">,</span></b>pos1<b><span style="color: rgb(102, 51, 0);">,</span></b>spd1<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex1<b><span style="color: rgb(102, 51, 0);">,</span></b> pos2<b><span style="color: rgb(102, 51, 0);">,</span></b> spd2<b><span style="color: rgb(102, 51, 0);">));</span></b>
<br /> spriteList<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">new</span> AutoSprite<b><span style="color: rgb(102, 51, 0);">(</span></b>tex2<b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 102, 0);">300.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">0.0f</span><b><span style="color: rgb(102, 51, 0);">),</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);"> (</span></b><span style="color: rgb(153, 102, 0);">1.0f</span><b><span style="color: rgb(102, 51, 0);">,</span></b><span style="color: rgb(153, 102, 0);">3.0f</span><b><span style="color: rgb(102, 51, 0);">)));</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>LoadContent<b><span style="color: rgb(102, 51, 0);">();
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>Sprite s in spriteList<b><span style="color: rgb(102, 51, 0);">) {</span></b>
<br /> s<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b><span style="color: rgb(153, 0, 0);">
<br />
<br /> public</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Begin<b><span style="color: rgb(102, 51, 0);">();</span></b>
<br /> foreach<b><span style="color: rgb(102, 51, 0);"> (</span></b>Sprite s in spriteList<b><span style="color: rgb(102, 51, 0);">)
<br /> {</span></b>
<br /> s<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">,</span></b>spriteBatch<b><span style="color: rgb(102, 51, 0);">);
<br /> }</span></b>
<br /> base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);</span></b>
<br /> spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>End<b><span style="color: rgb(102, 51, 0);">();
<br /> }
<br /> </span></b>
<br /><b><span style="color: rgb(102, 51, 0);"> }
<br />}</span></b></pre><span style="font-weight: bold;"><span style="font-weight: bold;">
<br /></span></span>Vediamo cosa abbiamo creato... <span style="font-weight: bold;"><span style="font-weight: bold;">
<br /></span></span><pre> SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> List<b><span style="color: rgb(102, 51, 0);"><</span></b>Sprite<b><span style="color: rgb(102, 51, 0);">></span></b> spriteList<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> List<b><span style="color: rgb(102, 51, 0);"><</span></b>Sprite<b><span style="color: rgb(102, 51, 0);">>();</span></b>
<br /> Texture2D tex1<b><span style="color: rgb(102, 51, 0);">,</span></b> tex2<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Vector2 pos1<b><span style="color: rgb(102, 51, 0);">,</span></b> pos2<b><span style="color: rgb(102, 51, 0);">;</span></b>
<br /> Vector2 spd1<b><span style="color: rgb(102, 51, 0);">,</span></b> spd2<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);">
<br /></span></pre>
<br />Fondamentalmente creiamo uno <span style="font-weight: bold;">spritebatch</span> dedicato unicamente al questo componente (utile per utilizzare il componente in altri programmi indipendentemente dalla loro struttura).
<br />Una <span style="font-weight: bold;">lista </span>dove inseriremo i vari oggetti di tipo sprite (o suoi derivati) e poi abbiamo due differenti <span style="font-weight: bold;">texture</span>, due informazioni di <span style="font-weight: bold;">posizione </span>e due <span style="font-weight: bold;">velocità</span>. Valorizzeremo questi elementi in seguito in diversi punti del codice, nella <span style="font-weight: bold;">initialize</span> ci occupiamo di dare un valore a posizioni e velocità.
<br />Nella load content caricheremo le texture dei nemici (incollo qui sotto le immagini da scaricare) e creiamo lo spritebatch dedicato (aggiungete le texture dei nemici ai contenuti... vi ricordo Add->exixting Item e scegliete le immagini).
<br /><pre><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu46fZetB7sIQfrJe91Xw03I8hI-FaaVMOi9gU6pGprat9lEFAIX8db4Nwkm6I_M50pHT1Vp9Oukebm1zKyH6IO4W8eF2hyBwvzOV_zffbdX5HUT2JPlOA4-UqUl9y_jNO-gWvDbHwlsI/s1600-h/enemy.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 45px; height: 56px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEiu46fZetB7sIQfrJe91Xw03I8hI-FaaVMOi9gU6pGprat9lEFAIX8db4Nwkm6I_M50pHT1Vp9Oukebm1zKyH6IO4W8eF2hyBwvzOV_zffbdX5HUT2JPlOA4-UqUl9y_jNO-gWvDbHwlsI/s400/enemy.png" alt="" id="BLOGGER_PHOTO_ID_5312066219056155010" border="0" /></a></pre> <pre><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifCcm8oDPLaFHsfTG6if3mtL6a9mDqfyHeRc3pot12xjaNTnewWjlgEHmpkWaeRU8HwEV2pd_5fMULLZNQO60QXB_5nxx0_RpzYBlsQILJPAnEOf3na6GO-Iy7Fom1v57SZVlFv_yXac0/s1600-h/enemy2.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 45px; height: 56px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEifCcm8oDPLaFHsfTG6if3mtL6a9mDqfyHeRc3pot12xjaNTnewWjlgEHmpkWaeRU8HwEV2pd_5fMULLZNQO60QXB_5nxx0_RpzYBlsQILJPAnEOf3na6GO-Iy7Fom1v57SZVlFv_yXac0/s400/enemy2.png" alt="" id="BLOGGER_PHOTO_ID_5312066596340107154" border="0" /></a></pre>
<br />Infine aggiungiamo alla lista di sprite 3 nuovi AutoSprite, ai primi due daremo le info settate nella initialize e il terzo lo valorizzermo direttamente dal costruttore. Nella <span style="font-weight: bold;">Update </span>e nella <span style="font-weight: bold;">Draw</span> ci occuperemo semplicemente di ciclare tutti gli oggetti della lista sprite e di chiamare i metodi Draw e Update degli oggetti (che sono appunto i metodi che abbiamo definito nelle classi Sprite e AutoSprite).
<br />
<br />Perfetto.... e ora?? come faremo rientrare le funzioni dello SpriteManager nel ciclo del programma?
<br />Qui arriva la parte goduriosa... bastano solo 2 righe di codice!
<br />Andate nella Initialize di Game1.cs e aggiungete in testa alla funzione queste due righe
<br />
<br /><pre>SpriteManager spritemanager<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b>
<br />Components<b><span style="color: rgb(102, 51, 0);">.</span></b>Add<b><span style="color: rgb(102, 51, 0);">(</span></b>spritemanager<b><span style="color: rgb(102, 51, 0);">);</span></b></pre>
<br />Questo passaggio fa si che venga creato un nuovo SpriteManager e venga aggiunto ai gamecomponents, da questo momento automaticamente entrerà nel ciclo di vita del programma, per intenderci ad ogni update di game1.cs ci sarà un update del nostro SpriteManager.
<br />Come potete vedere, nel file game1.cs non c'è traccia dei tre sprite che abbiamo incapsulato nello spriteManager e il tutto a questo punto è assolutamente indipendete e ordinato!
<br />
<br />Se non ho perso nessun pessaggio a questo punto dovreste poter compilare tranquillamente il codice e godervi le nostre 3 astronavi nemiche che svolazzeranno verso il basso, se ci fosse qualche errore dovuto ai copia e incolla dei codici... qui sotto trovate i sorgenti!
<br />
<br /><span style="font-weight: bold;">Qui sotto i codici sorgenti:</span>
<br /><a href="http://www.thinkandbuild.it/imparandoxna/2.SpriteManager.zip">2.spriteManager.zip</a>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com3tag:blogger.com,1999:blog-1511468527759599388.post-83539148711746415722009-03-09T14:12:00.000-07:002011-10-05T00:48:21.957-07:004) Xna Videogame Tutorial : Il primo spriteOoooh!!! Finalmente inizio a farvi vedere qualcosa di concreto! Avete presente un videogame FPS 3d con grafica generata proceduralmente, HLSL di ultima generazione che Directx 11 a confronto fa ridere, con esplosioni ed illuminazioni da panico?..... ecco benissimo! non faremo niente di tutto questo :D vi mostrerò semplicemente cosa dovrete fare per visualizzare la vostra piccola e piatta astronave 2d sul vostro monitor! ... lo so come inizio non è molto, eppure vedrete che vi darà soddisfazione.... da qualche parte bisogna pur partire!!<br /><br /><object width="340" height="285"><br /><param name="movie" value="http://www.youtube.com/v/XWZbew-ernc&hl=it&fs=1&color1=0x234900&color2=0x4e9e00&border=1"><br /><param name="allowFullScreen" value="true"><br /><param name="allowscriptaccess" value="always"><br /><embed src="http://www.youtube.com/v/XWZbew-ernc&hl=it&fs=1&color1=0x234900&color2=0x4e9e00&border=1" type="application/x-shockwave-flash" allowscriptaccess="always" allowfullscreen="true" width="340" height="285"></embed><br /></object><br /><br /><br />Dato che il tutorial vero e proprio inizierà qualche riga sotto vi consiglierei prima di tutto di chiedervi quale sia il vostro livello. Io parlerò di XNA in modo molto semplice, e gli argomenti di questi primi tutorial non saranno certamente complessi... ma.... se non avete una buona infarinatura di programmazione ad oggetti inizierei leggendo prima qualche guida o meglio ancora studiando un libro in modo approfondito.<br />Questo per esempio è gratuito ... <a target="_blank" href="http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html">http://www.mindview.net/Books/TICPP/ThinkingInCPP2e.html </a>tratta c++ ma vi assicuro che come conoscenza acquisibile va più che bene!<br /><br />Vi consiglio di studiare prima le basi perchè altrimenti questi semplici tutorial si trasformeranno in un inferno senza senso e a quel punto vi demoralizzerete mollando subito il colpo.<br />Scusate per questa triste premessa ma è da anni che desideravo scriverne una.<br /><br />Premesse demoralizzanti a parte .... su! mouse e tastiera e cominciamo!<br /><br /><span style="font-weight: bold;">Iniziamo:</span><br />Come vi ho anticipato nel post scorso, nei prossimi giorni svilupperemo un semplice videogame. Non avremo molte pretese se non quella di imparare alcuni concetti fondamentali legati alle basi di XNA!<br /><br />Quello con cui avremo a che fare oggi è la stampa di un'immagine 2d (la nostra astronave) che si muoverà da destra sinistra nella finestra di gioco.<br /><span style="font-weight: bold;"><br />Installazione:</span><br />Per chi di voi non avesse già installato XNA 3.0 e Visual C#2008:<br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX2n39x7nAu_0gIhqrfzU0LfbVYOxHYH5XUIEqxXWcpO106p6zk3j6YWAFFAVxcSNrCTYc7fFr01OfX3lriTsqCf4Jp7S0eu7uU8bo8PcwKmH9yZHgyNBdsO2WM2a0XE9F6qD2kXffXws/s1600-h/instal.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 231px; height: 152px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjX2n39x7nAu_0gIhqrfzU0LfbVYOxHYH5XUIEqxXWcpO106p6zk3j6YWAFFAVxcSNrCTYc7fFr01OfX3lriTsqCf4Jp7S0eu7uU8bo8PcwKmH9yZHgyNBdsO2WM2a0XE9F6qD2kXffXws/s320/instal.jpg" alt="" id="BLOGGER_PHOTO_ID_5311309187135620690" border="0" /></a><a href="http://www.microsoft.com/express/vcsharp/" target="_blank">Installer Visual C# 2008</a> A destra dovreste vedere un box simile a questo. Dopo aver scelto la vostra lingua preferita cliccate su download e scaricate l'.exe, quindi seguite la procedura di download e installazione.<br /><br /><br /><br /><br /><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5r7i8beVdbil6pSkdmr1aoCwCPfBCIHTD4lWNHYmWOjTLcqCuuzexHxzcKb0gnst1IP9eVCaL3yr6Z4VQ5hBmdiOEVjla-NCWaWiXjethijuzH8QlrevL6x7_PI9UC0C7hZnHVPHeB74/s1600-h/installxna.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 227px; height: 110px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg5r7i8beVdbil6pSkdmr1aoCwCPfBCIHTD4lWNHYmWOjTLcqCuuzexHxzcKb0gnst1IP9eVCaL3yr6Z4VQ5hBmdiOEVjla-NCWaWiXjethijuzH8QlrevL6x7_PI9UC0C7hZnHVPHeB74/s320/installxna.jpg" alt="" id="BLOGGER_PHOTO_ID_5311310512544004418" border="0" /></a><a target="_blank" href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7D70D6ED-1EDD-4852-9883-9A33C0AD8FEE&displaylang=en">Installer Game st</a><a href="http://www.microsoft.com/downloads/details.aspx?FamilyId=7D70D6ED-1EDD-4852-9883-9A33C0AD8FEE&displaylang=en">udio XNA 3.0</a> , anche in questo caso cliccate sul pulsante download scaricate e seguite le istruzioni.<br /><br /><br /><br /><br /><br /><br /><span style="font-weight: bold;">Creare il progetto:</span><br />Una volta installati entrambi i sw, lanciate Visual C# 2008 e create un nuovo progetto di tipo windows game (3.0). Vi metto un'immagine sgranata e illeggibile per aiutarvi a capire il passaggio :P, lo so è semplice.... non vi ho preso per rimbambiti! ma almeno così siete sicuri no? (io la prima volta non trovavo "windows game (3.0)" perchè non cliccavo sulla voce xna project, sotto a project types nella barra di sinistra .....<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvBGqY_ss4mgSyn6Xj-uoKJ_bjOe0dmvu0TBhkTO_0NT2Gy3DLq08N4sfan-UvOLk1a-A0HaJnVKk9foAbYauSk4yIcGowvBI1_HzpjsqvbYwwiD2NACKXtXd6dDWT4P5lLUJcSm3nW2o/s1600-h/newprj.jpg"><img style="cursor: pointer; width: 420px; height: 306px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEjvBGqY_ss4mgSyn6Xj-uoKJ_bjOe0dmvu0TBhkTO_0NT2Gy3DLq08N4sfan-UvOLk1a-A0HaJnVKk9foAbYauSk4yIcGowvBI1_HzpjsqvbYwwiD2NACKXtXd6dDWT4P5lLUJcSm3nW2o/s400/newprj.jpg" alt="" id="BLOGGER_PHOTO_ID_5311312913967492114" border="0" /></a><br /><br />Chiamate il progetto come meglio credete e posizionatelo nel vostro Hd nella cartella parent dello spazio dove archiviate i film hard, in questo modo la troverete subito quando dovrete riaprire il progetto tra qualche giorno!<br /><br />Ok...a questo punto troverete davanti a voi una finestra di visual c suddivisa in vari ambiti, purtroppo non ho moltissimo tempo per spiegarvi al meglio come sono disposti i contenuti nella finestra di Visual C, l'importante è notare che a destra avete una visualizzazione dei file e degli elementi che compongono il progetto, a sinistra il vostro codice e in basso un frame per messaggi d'errore (warnings.. etc).<br /><br /><span style="font-weight: bold;">I primi file:</span><br />Analiziamo molto velocemente i file presenti nella barra destra, cliccando su properties, e sul suo figlio <span style="font-weight: bold;">AssemblyInfo.cs</span> troverete un file di "configurazione" che sinceramente non mi è mai capitato di modificare.<br /><br /><span style="font-weight: bold;">Program.cs </span>è il punto d'ingresso del programma che creeremo, come potete notare qui si trova il metodo main, che chiama la funzione run dell'oggetto game di tipo Game1.<br />Il file <span style="font-weight: bold;">Game1.cs</span> è il file centrale del nostro programma, dove andremo a definire l'oggetto che viene richiamato da Program.cs e sarà il cuore del nostro videogame.<br />Aprendo questo file troverete alcune funzioni (che sono quelle che vi ho anticipato <a target="_blank" href="http://imparandoxna.blogspot.com/2009/02/cose-xna-e-come-funziona.html">qualche articolo fa</a> ).<br /><br /><span style="font-weight: bold;">Carichiamo l'immagine:</span><br />Il nostro scopo per oggi è quello di far muovere uno sprite nella nostra finestra di gioco, quindi prima di tutto dovremmo avere qualcosa da far muovere!<br /><br /><span style="font-style: italic;">Scaricate</span> questa immagine che sarà la nostra bellissima astronave! <a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_fq7K8uuD2O7bxeCHM6HgvUBerdbgTyxtbS68u39q1N2nid3_i7gekalUPadlRCKjIsw5rMz7ciCqeTmzFKMaG-QeGtxtlxfTmyAwCtEjOK0EeV5wklruRSxmrMI_lAskBQX0E2xRwG4/s1600-h/spaceship.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 47px; height: 53px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEg_fq7K8uuD2O7bxeCHM6HgvUBerdbgTyxtbS68u39q1N2nid3_i7gekalUPadlRCKjIsw5rMz7ciCqeTmzFKMaG-QeGtxtlxfTmyAwCtEjOK0EeV5wklruRSxmrMI_lAskBQX0E2xRwG4/s320/spaceship.png" alt="" id="BLOGGER_PHOTO_ID_5311306899035278146" border="0" /></a><br />(una nota su questa grafica. Purtroppo non riesco più a trovare la fonte dalla quale l'ho reperita, trattasi di un forum che penso sia stato cancellato... questo vale anche per le prossime immagini... se qualcuno di voi incontrasse in rete quest'immagine me lo faccia notare.. così linkero l'autore! grazie mille).<br /><br />Ora, il primo passaggio per inserire l'immagine tra i file dei quali potremmo disporre, è semplicemente cliccare con il tasto destro sulla voce "Content" nel frame dei contenuti a destra<br />e dunque "Add" e "Existing Item". A questo punto inseriremo l'immagine della nostra astronave (spaceship.png)<br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirT0N07kmjT74RDum-JrwNyVYXHd2nmvlOAgeABe1XD7N-EIXGBPdgHM98SsSrPyWBGoopMQl1SdQoQ-ZYOBJHPoZdQ0mRCEa5X-4VY6jlpITOTrO8v2N34MwcsgJ_bAQ6GIPGQQ2UIw0/s1600-h/addimg.jpg"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 290px; height: 285px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEirT0N07kmjT74RDum-JrwNyVYXHd2nmvlOAgeABe1XD7N-EIXGBPdgHM98SsSrPyWBGoopMQl1SdQoQ-ZYOBJHPoZdQ0mRCEa5X-4VY6jlpITOTrO8v2N34MwcsgJ_bAQ6GIPGQQ2UIw0/s400/addimg.jpg" alt="" id="BLOGGER_PHOTO_ID_5311319917813326114" border="0" /></a><br /><br /><br />Questo che per voi è stato un semplice passaggio di 3 click, in realtà racchiude un sistema di import e gestione dei contenuti mooooooolto interessante, trattasi della cosidetta <span style="font-weight: bold;">Content pipeline</span> di XNA.<br />Tramite questa comodissima features voi non dovrete assoultamente preoccuparvi di trovare un modello di importazione per i vostri contenuti, dato che questo lavoro lo farà XNA per voi...non vi parlo solo di jpg png etc... ma parliamo di file 3d come .X ( + altri formati) e audio (previa lavorazione con xact.. che vedremo più avanti) . Una cosa interessante di questa modalità è che comunque sarete liberi di <a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb447743.aspx">scrivere</a> un vostro importer(o di terze parti) o di <a target="_blank" href="http://msdn.microsoft.com/en-us/library/bb447748.aspx">estendendere</a> la content pipeline standard.<br /><br /><br /><span style="font-weight: bold;">Il primo codice:</span><br />A questo punto è il caso di iniziare a scrivere qualcosa ... dato che per ora ha fatto tutto xna per noi.<br />Vi ricordo che vogliamo stampare uno sprite della nostra astronave che si muova da destra a sinistra nella finestra di gioco.<br /><br />Gli elementi che entrano in gioco sono quindi:<br /><br />1) la grafica della nostra astronave<br />2) la posizione dell'astronave<br />3) la velocità dell'astronave<br />4) lo spazio entro il quale si potrà muovere (la finestra di gioco)<br /><br />Se date una ripassata alla lista delle funzioni che vi ho presentato qualche giorno fa (la trovate qui<br /><a target="_blank" href="http://imparandoxna.blogspot.com/2009/02/cose-xna-e-come-funziona.html">http://imparandoxna.blogspot.com/2009/02/cose-xna-e-come-funziona.html</a> )<br />noterete che ogni funzione ha degli scopi ben precisi, ora vi riassumerò in breve come utilizzeremo queste funzioni e sotto riporterò i vari codici:<br /><br />La funzione <span style="font-weight: bold;">Initialize</span> si occuperà di inizializzare la posizione di partenza dell'astronave, che vogliamo sia più o meno al centro della finestra.<br />La funzione <span style="font-weight: bold;">LoadContent</span> caricherà la texture della nostra astronave. Attraverso la funzione <span style="font-weight: bold;">Update</span> faremo variare il suo parametro posizione e nella <span style="font-weight: bold;">Draw</span> stamperemo l'astronave secondo il parametro calcolato nella update.<br /><br />Prima di tutto settiamo delle variabili di classe, prima della funzione Game1().<br /><br /><span style="font-weight: bold;">VARIABILI DI CLASSE e COSTRUTTORE</span><br /><pre><i><span style="color: rgb(153, 153, 153);"><br />//Impostazioni astronave-------------------------------------<br /></span></i>Texture2D tex_ship<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">//Texture atronave<br /></span></i>Vector2 pos_ship<b><span style="color: rgb(102, 51, 0);"> =</span></b> Vector2<b><span style="color: rgb(102, 51, 0);">.</span></b>Zero<b><span style="color: rgb(102, 51, 0);">;</span></b><i><span style="color: rgb(153, 153, 153);">//coordinate posizionali<br /></span></i><span style="color: rgb(255, 102, 51);">float</span> spd_ship<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 102, 0);"> 3.0f</span><b><span style="color: rgb(102, 51, 0);">;</span></b><i><span><i><span style="color: rgb(153, 153, 153);">//Velocità</span></i></span></i><br /><span style="color: rgb(153, 0, 0);"><br />public</span> Game1<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><br />graphics<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> GraphicsDeviceManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b><br />Content<b><span style="color: rgb(102, 51, 0);">.</span></b>RootDirectory<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Content"</span><b><span style="color: rgb(102, 51, 0);">;<br /><br />}<br /></span></b><span style="font-family:Georgia,serif;"><br /></span></pre>Il tipo Texture2d come potete immaginare serve per storicizzare informazioni di tipo immagine, mentre la vector2 rappresente un vettore a due chiavi (X,Y) e ha alcune funzionalità per facilitare la vita del programmatore come Vector2.Zero che setta automaticamente sia X che Y a 0.<br />L'oggetto GraphicsDeviceManager(this) è il riferimento alla nostra GPU, mentre la Content.RootDirecotory definisce il nome della cartella nella quale posizioneremo i contenuti da caricare tramite la ContentPipeline.<br /><br /><br /><span style="font-weight: bold;">INITIALIZE</span><br /><pre><span style="color: rgb(153, 0, 0);"><br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><i><span style="color: rgb(153, 153, 153);"><br />//Coordinate iniziali<br /></span></i><span style="color: rgb(255, 102, 51);"> float</span> x_pos<b><span style="color: rgb(102, 51, 0);"> = (</span></b>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Width<b><span style="color: rgb(102, 51, 0);"> /</span></b><span style="color: rgb(153, 153, 0);"> 2</span><b><span style="color: rgb(102, 51, 0);">);</span></b><span style="color: rgb(255, 102, 51);"><br />float</span> y_pos<b><span style="color: rgb(102, 51, 0);"> = (</span></b>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Height<b><span style="color: rgb(102, 51, 0);"> /</span></b><span style="color: rgb(153, 153, 0);"> 2</span><b><span style="color: rgb(102, 51, 0);">);</span></b><br />pos_ship<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b>x_pos<b><span style="color: rgb(102, 51, 0);">,</span></b> y_pos<b><span style="color: rgb(102, 51, 0);">);</span></b><br /><br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();<br />}</span></b></pre>Dunque nella initialize setteremo la posizione iniziale dell'astronave, prendendo la dimensione della nostra finestra <span style="font-family:monospace;"><br /></span>Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Width - Height e dividendo per due, quindi associeremo le posizioni calcolate alla posizione dell'astronave pos_ship.<br /><br /><br /><span style="font-weight: bold;">LOAD CONTENT</span><br /><br /><pre><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><br />spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b><br />tex_ship<b><span style="color: rgb(102, 51, 0);"> =</span></b> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);"><</span></b>Texture2D<b><span style="color: rgb(102, 51, 0);">>(</span></b>@<span style="color: rgb(0, 153, 0);">"spaceship"</span><b><span style="color: rgb(102, 51, 0);">);<br />}</span></b></pre><br />Nella LoadContent caricheremo la texture dell'astronave, non vi ho fatto notare prima che se cliccate sull'immagine caricate nell'area dei contenuti a destra e vi spostate a fondo pagina sotto la voce properties, vedrete le impostazioni legate all'immagine e insieme a queste il nome con il quale dovrete richiamare l'immagine nel vostro programma (in questo caso spaceship). Come noterete non vi preoccupate più dell'estensione del file immagine.<br />Infatti guardate come istanziamo l'oggetto Texture2d :<br /><span style="font-style: italic;">Content.Load<texture2d>(@"spaceship");</texture2d></span><br />Utilizziamo la funzione Load dell'oggetto content, facendo riferimento direttamente al nome che la contentpipeline ha associato per noi all'immagine caricata. (se avessimo inserito l'immagine nella cartella images avremo naturalmente dovuto riportare l'intero persorso "images/spaceship").<br />Per quanto riguarda lo spriteBatch si tratta dell'oggetto attraverso il quale stamperemo gli sprites.<br /><br /><br /><span style="font-weight: bold;">UPDATE</span><br /><span><pre><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><span style="color: rgb(153, 153, 153);"><br />// Allows the game to exit<br /></span><span style="color: rgb(255, 0, 0);"> if</span><b><span style="color: rgb(102, 51, 0);"> (</span></b>GamePad<b><span style="color: rgb(102, 51, 0);">.</span></b>GetState<b><span style="color: rgb(102, 51, 0);">(</span></b>PlayerIndex<b><span style="color: rgb(102, 51, 0);">.</span></b>One<b><span style="color: rgb(102, 51, 0);">).</span></b>Buttons<b><span style="color: rgb(102, 51, 0);">.</span></b>Back<b><span style="color: rgb(102, 51, 0);"> ==</span></b> ButtonState<b><span style="color: rgb(102, 51, 0);">.</span></b>Pressed<b><span style="color: rgb(102, 51, 0);">)</span></b><span style="color: rgb(153, 0, 0);"><br />this</span><b><span style="color: rgb(102, 51, 0);">.</span></b>Exit<b><span style="color: rgb(102, 51, 0);">();</span></b><br /><br />pos_ship<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);"> +=</span></b> spd_ship<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(255, 0, 0);"><br /><br />if</span><b><span style="color: rgb(102, 51, 0);"> (<br />(</span></b>pos_ship<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);"> ></span></b> Window<b><span style="color: rgb(102, 51, 0);">.</span></b>ClientBounds<b><span style="color: rgb(102, 51, 0);">.</span></b>Width<b><span style="color: rgb(102, 51, 0);"> -</span></b> tex_ship<b><span style="color: rgb(102, 51, 0);">.</span></b>Width<b><span style="color: rgb(102, 51, 0);">)<br />||</span></b><br />pos_ship<b><span style="color: rgb(102, 51, 0);">.</span></b>X<b><span style="color: rgb(102, 51, 0);"> <</span></b><span style="color: rgb(153, 153, 0);"> 0</span><b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><br />spd_ship<b><span style="color: rgb(102, 51, 0);"> *= -</span></b><span style="color: rgb(153, 153, 0);">1</span><b><span style="color: rgb(102, 51, 0);">;<br />}</span></b><br /><br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);<br />}</span></b></pre><br /></span>Finalmente entriamo nel loop, la funzione update a ogni ciclo modificherà la posizione X dell'astronave, quando l'astronave arriverà contro la parete di sinistra<br /><span style="font-style: italic;">(pos_ship.X > Window.ClientBounds.Width - tex_ship.Width)</span> invertirà la sua rotta <span style="font-style: italic;"><span style="font-style: italic;">(spd_ship *= -1;)</span></span>....quando incontrerà la parete di destra <span style="font-style: italic;">(pos_ship.X < style="font-style: italic;"> (spd_ship *= -1;)</span><br /><span><span style="font-style: italic;">Per ora tralasciate la riga dove viene intercettato l'input da Pad (if (GamePad.GetState... etcc) ne parleremo più avanti.</span><br /><br /><span style="font-weight: bold;">DRAW</span><br /><pre><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><br />GraphicsDevice<b><span style="color: rgb(102, 51, 0);">.</span></b>Clear<b><span style="color: rgb(102, 51, 0);">(</span></b>Color<b><span style="color: rgb(102, 51, 0);">.</span></b>CornflowerBlue<b><span style="color: rgb(102, 51, 0);">);</span></b><br /><br />spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Begin<b><span style="color: rgb(102, 51, 0);">();</span></b><br />spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>tex_ship<b><span style="color: rgb(102, 51, 0);">,</span></b> pos_ship<b><span style="color: rgb(102, 51, 0);">,</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>White<b><span style="color: rgb(102, 51, 0);">);</span></b><br />spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>End<b><span style="color: rgb(102, 51, 0);">();</span></b><br /><br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);<br />}<br /></span></b><br /></pre></span><span>E infine disegnamo l'astronave nella posizione definita nell'update<br />Ci cureremo di inserire la funzione SpriteBatch.Draw tra i metodi Begin() e End() dopo aver "pulito" la schermata (con la funzione Clear) da quanto stampato nel ciclo precedente, se non ci curassimo di cancellare le info stampate nel ciclo precedente vedremmo la nostra astronava ripetuta tante volte quante volte si è entrati nel ciclo update-draw.<br /></span><span>La funzione Draw dell'oggetto spriteBatch ha diversi prototipi che accettano diversi <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritebatch.draw.aspx">parametri </a>, per ora tenete solo in testa che lo spritebatch è come la vostra lavagna, e che attraverso il metodo draw, sopra utilizzato, andate a definire<br />1) quale immagine stampare (tex_ship)<br />2) in che posizione (pos_ship)<br />3) eventualmente una tinta, .White è neutro.<br /><br />Tramite lo spritebatch potete gestire anche ordini di stampa trasparenze e modalità di visualizzazione, dando dei <a href="http://msdn.microsoft.com/en-us/library/microsoft.xna.framework.graphics.spritebatch.begin.aspx">parametri alla funzione Begin()</a> .<br /><br /><br /><span style="font-weight: bold;">Fine</span><br />A questo punto cliccando su f5 se avete seguito quello che ho scritto qui sopra, dovreste vedere la nostra astronave muoversi da destra a sinistra e rimbalzare nello schermo come una pallina!<br /><br /><br />Bravi! Per oggi basta così perchè sono veramente fuso.... pensavo di non aver niente da dire su questo argomento e invece mi sembra di essermi dilungato fin troppo, spero di non avervi addirittura annoiato.<br /><br />Con le prossime cercherò di essere più rapido!!<br /><br />Download Sorgenti:<br /><a target="_blank" href="http://www.thinkandbuild.it/imparandoxna/1.sprite2d.zip">1.sprite2d.zip</a><br /><br />Ciao a tutti<br /><br /></span><span style="font-style: italic;"><br /><br /><br /><br /><br /><br /><br /><br /><br /></span>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com8tag:blogger.com,1999:blog-1511468527759599388.post-68842989469943372152009-03-03T08:00:00.000-08:002009-03-11T12:49:49.567-07:003) Creare un semplice videogame in grafica 2D con XNAIl titolo di questo post racchiude veramente molte tematiche!<br />Non fatevi ingannare dal termine "Semplice Videogame", dato che per svilupparlo dovremo avere a che fare con gestione della grafica, input dell'utente, collisioni, audio, un minimo di intelligenza artificiale e stati del gioco.<br />Il mio intento è quello di produrre un piccolo gioco, che vedrà protagonista un'astronave impegnata nello schivare altri oggetti voltanti e astronavi.... ok bhe niente di veramente innovativo lo ammetto :P, ma prenderò spunto dal libro che sto studiando in questi giorni (che guardacaso presenta proprio un progetto simile) e semplificando un pò il succo del discorso cercherò di riproporvi quanto ho imparato.<br /><br />Come vi ho accennato sopra, per portare a termine questo "Semplice Videogame" passeremo per vari argomenti;<br /><span style="font-weight: bold;"><br />Questa è "l'indice" che seguirò per i prossimi post <span style="color: rgb(255, 0, 0);">(MODIFICATO)</span>:</span><br />- Grafica 2d visualizzare e animare uno sprite<br />- GameComponents<br />- Intercettare e gestire l'input<br />- Collisioni<br />- Gestione dell'Audio<br />- Punteggio e Modificatori (powerUp)<br />- Stati di Gioco (menu, in game , game over)<br /><br />In seguito:<br />Fisica e Intelligenza Artificiale<br /><br />Premetto che mi capita spesso di imbattermi in lunghe guide che portano avanti gli argomenti in maniera sequenziale, quindi se non si è interessanti ad un capitoletto irrimediabilmente si perde tutto il filo del discorso. I sorgenti vengono dati solo come startup e poi incrementati dal lettore man a mano che segue le lezioni.<br />Vorrei evitare di sottoporvi a una tortura simile, che se da un lato obbliga a seguire con criterio, dall'altro presuppone che il lettore sia interessato all'intera guida, supposizione che potrebbe non essere corretta :P . Quindi prima di ogni post allegherò i codici sorgenti iniziali e quelli finali, sperando di rendere il tutto un pò più semplice e leggero da seguire e permettendovi di partire da qualsiasi punto della "mini guida".<br /><br />Credo che riuscirò a mettere online la prima "lezione" già da settimana prossima!<br /><br />A presto !Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com6tag:blogger.com,1999:blog-1511468527759599388.post-45516076339034451452009-02-26T03:36:00.000-08:002009-03-02T12:59:25.118-08:002) Cos'è XNA e come funziona<span style="font-weight: bold;font-family:onload;" > </span><span style="font-family:arial;">XNA è un insieme di tool sviluppati da Microsoft con lo scopo di semplificare il processo di creazione di Videogame (o applicazioni interattive). E' basato su .NET e per tanto sfrutta uno dei linguaggi compatibili (consigliato c#) e si appoggia a DirectX per la gestione della grafica. Ad oggi siamo arrivati alla versione 3.0 ed olte a varie </span><a style="font-family: arial;" href="http://creators.xna.com/it-IT/article/xna3.0whatsnew">migliorie </a><span style="font-family:arial;">rispetto alla versione 2.0, ha un gran vantaggio, ovvero la possibilità di utilizzare Visual studio 2008 (fino alla versione 2.0 avreste dovuto utilizzare la 2005).</span> <span style="font-family:arial;">XNA implenta un </span><a style="font-family: arial;" href="http://en.wikipedia.org/wiki/Microsoft_XNA#XNA_Framework">framework</a><span style="font-family:arial;"> molto completo, che consente di interagire facilmente con Audio, Input e Device grafico.</span> <span style="font-family:arial;">Uno dei punti di forza di questo sistema è l'utilizzo di una </span><a style="font-family: arial;" href="http://blogs.msdn.com/xna/archive/2006/08/29/730168.aspx">content pipeline</a><span style="font-family:arial;"> utilizzata per caricare con facilità materiali come modelli 3d e texture, e renderli raggiungibili all'interno del nostro programma senza doversi preoccupare di inventare layer o modelli di importazione complessi (cosa che programmando sfruttando openGL o DirectX sarebbe altrimenti necessaria).</span> <span style="font-family:arial;"><br />Un altro elemento molto interessante è l'utilizzo dei gameComponents che vi descriverò meglio tra qualche articolo, per ora diciamo che sono un ottimo modo per incapsulare informazioni implementando un'interfaccia software comune a tutti i componenti.<br />Da quello che ho potuto capire, il workflow di xna è basato su un loop continuo (che vi mostro in un'immagine riassuntiva) che si differenzia dalla normale logica cosidetta di pooling , dove a seguito di una richiesta (esempio pressione di un pulsante) viene attivato un evento.</span> <span style="font-family:arial;">In generale il workflow presentato da XNA è comunque "standard" per quello che concerne il game development. Ricordo di aver visto qualcosa di molto simile leggendo questo </span><a style="font-family: arial;" href="http://www.amazon.com/Introduction-Game-Programming-Direct-9-0c/dp/1598220160">libro</a><span style="font-family:arial;"> su directx, libro che naturalmente non ho mai realmente approfondito :P , ma che si è comunque dimostrato parecchio utile per capire le basi del game development e avere qualche nozione matematica in più.</span> <span style="font-family:arial;"><br /><br /><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8yMWngGDCadPpSWwUzfC1ZtEsXGC353FsGlRe3RayKq9XRRnerppUuc3bdiRlZ2bS2PpUklxQ7B5po09W7_dIfe1trfHHavzmlTwGMdcUAaYlq0kvNRfWgu6_AKwTiEhOKKm7V113Bg/s1600-h/xna_gameloop.jpeg"><img style="cursor: pointer; width: 318px; height: 199px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEgY8yMWngGDCadPpSWwUzfC1ZtEsXGC353FsGlRe3RayKq9XRRnerppUuc3bdiRlZ2bS2PpUklxQ7B5po09W7_dIfe1trfHHavzmlTwGMdcUAaYlq0kvNRfWgu6_AKwTiEhOKKm7V113Bg/s400/xna_gameloop.jpeg" alt="" id="BLOGGER_PHOTO_ID_5307084860519947666" border="0" /></a><br /><br /></span><span style="font-family:arial;">e qui sotto .......tadaaaan il primo semplice esempio in C# dove vedete tutti gli step descritti nell'immagine.</span><br /><span style="font-family:arial;"><br /></span> <div style="border: 1px solid rgb(205, 205, 205); padding: 10px; width: 450px;font-family:arial;"><pre><span style="color: rgb(153, 0, 0);">using</span> System<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br />using</span> System<b><span style="color: rgb(102, 51, 0);">.</span></b>Collections<b><span style="color: rgb(102, 51, 0);">.</span></b>Generic<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Content<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>GamerServices<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br />using</span> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Input<b><span style="color: rgb(102, 51, 0);">;</span></b><span style="color: rgb(153, 0, 0);"><br /><br />namespace</span> <b><span style="color: rgb(102, 51, 0);">xwingGame<br />{</span></b><span style="color: rgb(153, 0, 0);"><br /><br />public class</span> Game1<b><span style="color: rgb(102, 51, 0);"> :</span></b> Microsoft<b><span style="color: rgb(102, 51, 0);">.</span></b>Xna<b><span style="color: rgb(102, 51, 0);">.</span></b>Framework<b><span style="color: rgb(102, 51, 0);">.</span></b>Game<b><span style="color: rgb(102, 51, 0);"><br />{</span></b><br />GraphicsDeviceManager graphics<b><span style="color: rgb(102, 51, 0);">;</span></b><br />SpriteBatch spriteBatch<b><span style="color: rgb(102, 51, 0);">;</span></b><br />Texture2D xwing<b><span style="color: rgb(102, 51, 0);">;</span></b>//Qui caricheremo un'immagine<br />Vector2 pos;//e questa sarà la sua posizione<span style="color: rgb(153, 0, 0);"><br /><br />public</span> Game1<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><br />graphics<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> GraphicsDeviceManager<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(153, 0, 0);">this</span><b><span style="color: rgb(102, 51, 0);">);</span></b><br />Content<b><span style="color: rgb(102, 51, 0);">.</span></b>RootDirectory<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(0, 153, 0);"> "Content"</span><b><span style="color: rgb(102, 51, 0);">;<br />}</span></b><span style="color: rgb(153, 0, 0);"><br /><br /><br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Initialize<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><br />spriteBatch<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> SpriteBatch<b><span style="color: rgb(102, 51, 0);">(</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">);</span></b><br />pos<b><span style="color: rgb(102, 51, 0);"> =</span></b><span style="color: rgb(153, 0, 0);"> new</span> Vector2<b><span style="color: rgb(102, 51, 0);">(</span></b>0f<b><span style="color: rgb(102, 51, 0);">,</span></b> 0f<b><span style="color: rgb(102, 51, 0);">);</span></b><br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Initialize<b><span style="color: rgb(102, 51, 0);">();<br />}</span></b><span style="color: rgb(153, 0, 0);"><br /><br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> LoadContent<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><br />xwing<b><span style="color: rgb(102, 51, 0);"> =</span></b> Content<b><span style="color: rgb(102, 51, 0);">.</span></b>Load<b><span style="color: rgb(102, 51, 0);">(</span></b><span style="color: rgb(0, 153, 0);">"images/xwing.png"</span><b><span style="color: rgb(102, 51, 0);">);<br />}</span></b><span style="color: rgb(153, 0, 0);"><br /><br /></span><span style="color: rgb(153, 0, 0);">protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> UnLoadContent<b><span style="color: rgb(102, 51, 0);">()<br />{</span></b><br /><b><span style="color: rgb(102, 51, 0);"><br />}</span></b><span style="color: rgb(153, 0, 0);"><br /></span><br /><span style="color: rgb(153, 0, 0);"><br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Update<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);<br />}</span></b><span style="color: rgb(153, 0, 0);"><br /><br />protected</span> override<span style="color: rgb(255, 102, 51);"> void</span> Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>GameTime gameTime<b><span style="color: rgb(102, 51, 0);">)<br />{</span></b><br /><br />graphics<b><span style="color: rgb(102, 51, 0);">.</span></b>GraphicsDevice<b><span style="color: rgb(102, 51, 0);">.</span></b>Clear<b><span style="color: rgb(102, 51, 0);">(</span></b>Color<b><span style="color: rgb(102, 51, 0);">.</span></b>CornflowerBlue<b><span style="color: rgb(102, 51, 0);">);</span></b><br /><br />spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Begin<b><span style="color: rgb(102, 51, 0);">(</span></b><b><span style="color: rgb(102, 51, 0);">);</span></b><br />spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>xwing<b><span style="color: rgb(102, 51, 0);">,</span></b> pos<b><span style="color: rgb(102, 51, 0);">,</span></b> Color<b><span style="color: rgb(102, 51, 0);">.</span></b>White<b><span style="color: rgb(102, 51, 0);">);</span></b><br />spriteBatch<b><span style="color: rgb(102, 51, 0);">.</span></b>End<b><span style="color: rgb(102, 51, 0);">();</span></b><br /><br />base<b><span style="color: rgb(102, 51, 0);">.</span></b>Draw<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<b><span style="color: rgb(102, 51, 0);">);<br />}<br /><br />}//fine class game1<br />}//fine namespace</span></b></pre><br /></div> <sp style="font-family:arial;"><n><br />Non entro nei particolari di questo codice ma vi descriverò tutte le funzioni che sono presenti nel woorkflow visto nell'immagine:<br /><br /><span style="font-weight: bold;">Initialize()<br /></span>In questo punto vengono instanziate le variabili e le classi principali che andremo a riutilizzare in molto altre funzioni.<br /><br /><span style="font-weight: bold;">LoadContent()<br /></span>Questa funzione è dedicata al caricamento di tutti gli elementi che sfrutteranno la content pipeline. Quindi qui caricheremo suoni, texture e modelli 3d per esempio.<br /><br /><span style="font-weight: bold;">UnloadContent()<br /></span>Richiamata quando sarà necessario eliminare tutti i contenuti caricati tramite la LoadContent(). </n></sp><sp style="font-family:arial;"><n><span style="font-weight: bold;"><br /></span><br /><span style="font-weight: bold;">Update(gameTime)<br /></span>Qui entriamo nel game loop, questa funzione verrà chiamata ripetutamente per tutta la durata del programma ed è il punto dedicato alle operazioni cosidette di business, o meglio dove verranno inserite le modifiche ai dati del nostro programma.<br />Un semplice esempio: se volete che la vostra astronave alla pressione del tasto "freccia sinistra" si sposti a sinistra, è proprio nell'update() che adnremoa verificare che il tasto sinistro sia premuto... e in tal caso incrementeremo pos.x dove è salvata la posizione dell'astronave.<br />Come potete notare a questa funzione viene passata una variabile di tipo gameTime, che servirà per eventuali operazioni basate sulla quantità di tempo trascorso...e sopratutto come parametro da passare alla funzione Update della class padre</n></sp>: <pre style="font-family:arial;">base<b><span style="color: rgb(102, 51, 0);">.</span></b>Update<b><span style="color: rgb(102, 51, 0);">(</span></b>gameTime<span style="font-weight: bold;">)<br /></span></pre><pre style="font-family:arial;"><span style="font-size:100%;">Che al momento sinceramente non so dirvi come utilizzi tale variabile.... :P<br />uno degli utlizzi, immagino potrebbe essere quello di gestire il framerate. </span></pre> <sp style="font-family:arial;"><n><span style="font-weight: bold;">Draw(gameTime)<br /></span>Siamo sempre all'interno del loop... questa funzione si occuperà di gestire l'output a monitor. E sarà il punto dove andremo a definire tutti gli elementi inerenti quindi la parte grafica. Tornando all'esempio di prima, attraverso la funzione Draw() viene effettivamente disegnata l'astronave nella posizione che abbiamo modificato nell'update... o nella posizione del ciclo precedente nel caso in cui non ci siano state modifiche.<br /><br />Chiudo qui questo primo articolo di introduzione che penso possa essere utile sopratutto a chi è alle primissime armi, per capire almeno i primi concetti di base. Nel prossimo articolo partiremo con lo sviluppo vero e proprio iniziando a gettare le basi per un semplice (ma non troppo:P) gioco in 2d. Nello specifico vi mostrerò come si gestisce il caricamento di immagini nella finestra di gioco e vi mostrerò l'importanza dei GameComponents sopra citati.<br />Vi ricordo che lo scopo di questo blog è di mostrare un pò per volta quello che sto imparando. Quindi nel caso in cui ci fosserò dei punti che non vi tornano o nel caso in cui io avessi scritto qualcosa di sbagliato :P non abbiate pietà!<br /><br />Ciao!! alla prossima<br /><br /><span style="font-weight: bold;"></span><span style="font-weight: bold;"></span><span style="font-weight: bold;"></span><br /><br /></n></sp>Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com4tag:blogger.com,1999:blog-1511468527759599388.post-15911938069919936222009-02-12T11:43:00.000-08:002009-02-26T05:00:20.722-08:001) Presentazione<div style="text-align: left;"><br /></div><a onblur="try {parent.deselectBloggerImageGracefully();} catch(e) {}" href="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia2a_ARCxr0Bb7fp-KCCodCe3mRZagSZtrO7fKSIri37NFeiULBcRe6EA-HPJpOfIoUQxDX87GSZ4SEe2qBwtHAx4fulDKYjwcjB7ey6Hk9fRgq96a_l51Z9UHJA7hoFg3gLOjTPYiH1c/s1600-h/xna.png"><img style="margin: 0pt 10px 10px 0pt; float: left; cursor: pointer; width: 64px; height: 64px;" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEia2a_ARCxr0Bb7fp-KCCodCe3mRZagSZtrO7fKSIri37NFeiULBcRe6EA-HPJpOfIoUQxDX87GSZ4SEe2qBwtHAx4fulDKYjwcjB7ey6Hk9fRgq96a_l51Z9UHJA7hoFg3gLOjTPYiH1c/s320/xna.png" alt="" id="BLOGGER_PHOTO_ID_5302003261345745314" border="0" /></a><br />Ciao a tutti!<br />Vi presento il nuovo spazio dedicato al mio percorso di apprendimento di XNA.<br /><br /><br />Lo scopo per il quale ho aperto questo blog, è unicamente quello di divulgare quanto sto imparando, proponendo semplici tutorial e miniguide.<br />Essendo assolutamente neofita in questo ambito, penso di poter esprimere in modo facilmente comprensibile i concetti che sto apprendendo, dando risalto sopratutto agli ostacoli più ostici da superare. Questo tipo di approccio dovrebbe aiutare, chi come me, vuole cimentarsi nel campo dello sviluppo di videogame con XNA partendo dalle basi.<br /><br />Al momento sto per finire il libro LEARNING XNA 3.0 di Aaron Reed (uhm.. si possono citare fonti o mi denunciano?:P ) un professore della Neumont University. Devo dire che tratta tutti i concetti in maniera molto semplice e chiara e che per ora si sta rivelando un'ottima fonte..... Ve ne parlerò meglio nei prossimi post.<br /><br />Per concludere vorrei dirvi che per motivi di tempo, non tratterò le basi del C# o altri argomenti legati alla programmazione in generale, ma mi concentrerò unicamente su articoli legati a XNA.<br />Cercherò comunque di fornirvi risorse utili per approfondire argomenti di base (come la programmazione a oggetti e le Matrici... giusto per intenderci...) .<br /><br />Spero che questo primo post stimoli un pò la vostra curiosità, scrivetemi se avete suggerimenti o richieste particolari.... così almeno mi gaso un pò e cerco di pubblicare un prima di Aprile 2009 :D<br /><br />Ciao!Yari ( ImparandoXNA )http://www.blogger.com/profile/14917873770627360267noreply@blogger.com5