A7. Gestire il testo
Creando altri file *.lvl, il gioco procede, ma senza alcuna interruzione. Quello che vorremmo fare ora à scrivere sullo schermo, alla fine di ogni livello, una frase, ad esempio "Congratulazioni! Hai completato il livello!" e fermare il gioco in attesa della pressione di un tasto.
Per disegnare un testo, normalmente, si fa uso della classe SpriteFont, la quale viene creata e gestita dal ContentManager, uno strumento che è installato solo nel compilatore C#. Quindi, in assenza di questo, dobbiamo arrangiarci e cercare un altro modo per stampare una scritta sullo schermo. La soluzione è molto semplice: trasformare il testo in un'immagine, grazie alla classe Graphics, e usare questa immagine come sprite. Ho scritto una classe appositamente per questo:
Ora aggiungiamo un oggetto GameText di nome SubTitle e modifichiamo il codicePublic Class GameTextInherits GameObject 'Font usato per scrivere Private _FontAs Drawing.Font 'Testo vero e proprio Private _TextAs String Public Property Font()As Drawing.FontGet Return _FontEnd Get Set (ByVal valueAs Drawing.Font) _Font = valueEnd Set End Property Public Property Text()As String Get Return _TextEnd Get Set (ByVal valueAs String ) _Text = valueEnd Set End Property Sub New ()My Base.New()End Sub Public Sub CreateSprite(ByVal DeviceAs GraphicsDevice) 'Crea una nuova bitmap di dimensioni 100x100. 'Le dimensioni non sono importanti, ma sono i parametri 'più semplici del costruttore Dim BAs New Drawing.Bitmap(100, 100) 'Crea una Graphics dalla bitmap Dim GAs Drawing.Graphics = Drawing.Graphics.FromImage(B) 'Calcola le dimensioni del testo Dim StringSizeAs Drawing.SizeF = _ G.MeasureString(Me .Text,Me .Font) 'Il metodo Graphics.DrawString richiede un pennello 'Brush, il quale viene costruito passandogli il 'colore desiderato. Tuttavia, il colore è espresso 'dalla struttura Drawing.Color e non da 'Xna.Framework.Graphics.Color. Quindi dobbiamo 'convertire manualmente il colore usando le sue 'componenti Alpha, Red, Green e Blue Dim DrawingColorAs Drawing.Color = _ Drawing.Color.FromArgb(Me .Color.A,Me .Color.R, _Me .Color.G,Me .Color.B) 'Stream che conterrà l'immagine Dim StreamAs IO.MemoryStream 'Reinizializza la bitmap con le dimensioni del testo B =New Drawing.Bitmap(CInt(StringSize.Width), _ CInt(StringSize.Height)) 'E di conseguenza, dicostruisce un'altra graphics G = Drawing.Graphics.FromImage(B) 'Imposta gli algoritmi di disegno G.TextRenderingHint = _ Drawing.Text.TextRenderingHint.AntiAliasGridFit G.SmoothingMode = Drawing.Drawing2D.SmoothingMode.AntiAlias 'Disegna la stringa G.DrawString(Me .Text,Me .Font, _New Drawing.SolidBrush(DrawingColor), 0, 0) 'Inizializza lo stream, come stream in memoria Stream =New IO.MemoryStream 'Salva l'immagine sullo stream, in formato png '(lo usiamo perchè supporta la trasparenza) B.Save(Stream, Drawing.Imaging.ImageFormat.Png) 'Imposta la posizione di lettura all'inizio dello stream. 'Questa operazione è obbligatoria, poiché 'il metodo Texture2D.FromFile richiede che lo stream 'passato sia aperto e pronto alla lettura Stream.Position = 0 'Carica lo sprite a partire dallo stream Me .Sprite = Texture2D.FromFile(Device, Stream) Stream.Close()End Sub End Class
Con questo nuovo codice, una volta abbattuti tutti i blocchi, visualizza il messaggio, aspetta che venga premuto invio, e passa al livello successivo, come mostrato da questo video. Potete fare la stessa cosa anche per il completamento del gioco.Public Class Game '... 'Testo visualizzato alla fine del livello Private SubTitleAs GameText '... Protected Overrides Sub LoadContent()My Base.LoadContent() Background =New GameObject(GetTexture("Background.png")) Background.Position = Background.CenterDim SizeAs New Viewport Size.Width = Background.Sprite.Width Size.Height = Background.Sprite.Height Size.X = 0 Size.Y = 0Me .Graphics.GraphicsDevice.Viewport = SizeMe .Graphics.PreferredBackBufferHeight = Size.HeightMe .Graphics.PreferredBackBufferWidth = Size.WidthMe .Graphics.ApplyChanges() Bat =New GameObject(GetTexture("Bat.png")) Bat.Position =New Vector2( _Me .Graphics.GraphicsDevice.Viewport.Width / 2, _Me .Graphics.GraphicsDevice.Viewport.Height - 40) Ball =New GameObject(GetTexture("Ball.png")) Ball.Position =New Vector2( _Me .Graphics.GraphicsDevice.Viewport.Width / 2, _Me .Graphics.GraphicsDevice.Viewport.Height / 2) Ball.Velocity =New Vector2(0, BallSpeed) 'Crea il nuovo oggetto SubTitle =New GameText() 'Imposta il font da usare SubTitle.Font =New Drawing.Font("Monotype Corsiva", _ 30, Drawing.FontStyle.Italic) 'Imposta il testo SubTitle.Text = "Congratulazioni! Hai completato il livello!" & _ vbCrLf & "Premi invio per continuare" 'Crea il suo sprite, basandosi sul dispositivo 'grafico correntemente usato SubTitle.CreateSprite(Me .Graphics.GraphicsDevice) 'Imposta la posizione SubTitle.Position =New Vector2( _Me .GraphicsDevice.Viewport.Width / 2 - SubTitle.Sprite.Width / 2, 300) AdvanceLevel()End Sub '... Protected Overrides Sub Update(ByVal GameTimeAs GameTime) 'Controlla i tasti premuti, ma solo se il giocatore non 'ha ancora finito il livello If (Not LevelCompleted)Then KeyboardCheck() 'Controlla le collisioni CollisionCheck() 'Cambia la posizione della palla a seconda della sua velocità Ball.Position += Ball.VelocityElse 'Altrimenti attende la pressione di Invio per continuare If Keyboard.GetState.IsKeyDown(Keys.Enter)Then AdvanceLevel()End If End If If Blocks.Count = 0Then LevelCompleted = TrueEnd If My Base.Update(GameTime)End Sub Protected Overrides Sub Draw(ByVal gameTimeAs GameTime)Me .Graphics.GraphicsDevice.Clear(Color.White) Batch.Begin() Background.Draw(Batch) Bat.Draw(Batch) Ball.Draw(Batch)For Each BlockAs GameObjectIn Blocks Block.Draw(Batch)Next 'Se il livello è completato, visualizza il messaggio If LevelCompletedThen SubTitle.Draw(Batch)End If Batch.End()My Base.Draw(gameTime)End Sub End Class
Ora che è tutto scritto, potete anche aggiungere dei bonus, mettere della musica (usando la classe Audio illustrata nella guida), inserire nuovi blocchi, magari che si muovano da soli. Qui di seguito ci sono i download del progetto intero:
- XNA Proof : il mio progetto di prova. Qui è contenuto tutto il progetto fatto nella guida, completamente commentato
- Breakout : questo è lo stesso progetto, ma senza commenti. Include una schermata di presentazione, implementa la musica e i suoi e alcuni bonus
The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.



