Casino online









Mercato forex






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:
Public Class GameText
    Inherits GameObject

    'Font usato per scrivere
    Private _Font As Drawing.Font
    'Testo vero e proprio
    Private _Text As String

    Public Property Font() As Drawing.Font
        Get
            Return _Font
        End Get
        Set(ByVal value As Drawing.Font)
            _Font = value
        End Set
    End Property

    Public Property Text() As String
        Get
            Return _Text
        End Get
        Set(ByVal value As String)
            _Text = value
        End Set
    End Property

    Sub New()
        MyBase.New()
    End Sub

    Public Sub CreateSprite(ByVal Device As GraphicsDevice)
        'Crea una nuova bitmap di dimensioni 100x100.
        'Le dimensioni non sono importanti, ma sono i parametri
        'più semplici del costruttore
        Dim B As New Drawing.Bitmap(100, 100)
        'Crea una Graphics dalla bitmap
        Dim G As Drawing.Graphics = Drawing.Graphics.FromImage(B)
        'Calcola le dimensioni del testo
        Dim StringSize As 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 DrawingColor As Drawing.Color = _
            Drawing.Color.FromArgb(Me.Color.A, Me.Color.R, _
            Me.Color.G, Me.Color.B)
        'Stream che conterrà l'immagine
        Dim Stream As 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 
Ora aggiungiamo un oggetto GameText di nome SubTitle e modifichiamo il codice
Public Class Game
    '...
    
    'Testo visualizzato alla fine del livello
    Private SubTitle As GameText
    
    '...
    
     Protected Overrides Sub LoadContent()
        MyBase.LoadContent()

        Background = New GameObject(GetTexture("Background.png"))
        Background.Position = Background.Center

        Dim Size As New Viewport
        Size.Width = Background.Sprite.Width
        Size.Height = Background.Sprite.Height
        Size.X = 0
        Size.Y = 0
        Me.Graphics.GraphicsDevice.Viewport = Size
        Me.Graphics.PreferredBackBufferHeight = Size.Height
        Me.Graphics.PreferredBackBufferWidth = Size.Width
        Me.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 GameTime As 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.Velocity
        Else
            'Altrimenti attende la pressione di Invio per continuare
            If Keyboard.GetState.IsKeyDown(Keys.Enter) Then
                AdvanceLevel()
            End If
        End If

        If Blocks.Count = 0 Then
            LevelCompleted = True
        End If

        MyBase.Update(GameTime)
    End Sub
    
    Protected Overrides Sub Draw(ByVal gameTime As GameTime)
        Me.Graphics.GraphicsDevice.Clear(Color.White)

        Batch.Begin()

        Background.Draw(Batch)

        Bat.Draw(Batch)
        Ball.Draw(Batch)
        For Each Block As GameObject In Blocks
            Block.Draw(Batch)
        Next

        'Se il livello è completato, visualizza il messaggio
        If LevelCompleted Then
            SubTitle.Draw(Batch)
        End If

        Batch.End()

        MyBase.Draw(gameTime)
    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.

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: In entrambi non ci sono livelli già fatti. Per esercizio, potete scrivere un editor di livelli.





 

The Totem's Lair - Copyright (C) 2009
È vietata la riproduzione sia totale che parziale del sito.