Casino online









Mercato forex






A5. Gestire le collisioni - Parte II


La mazza c'è, la palla c'è, lo sfondo anche, le collisioni sono impostate ottimamente, ma... mancano i blocchi da rompere. Metteremo diversi blocchetti sparsi per lo schermo, che dovranno essere tutti colpiti e frantumati con la palla per completare il livello. I più fragili saranno da colpire una sola volta, mentre quelli più resistenti più volte. Per questo scopo, abbiamo bisogno di una nuova classe, Block, che rappresenti il blocchetto e la sua "vita". Tale classe andrà scritta nel file GameObjects.vb, insieme alla classe GameObject:
Public Class Block
    'Il blocco è pur sempre un oggetto del gioco, quindi
    'eredita da GameObject
    Inherits GameObject

    '"Vita" del blocco, ossia il numero di colpi necessari
    'a romperlo. Default = 1
    Private _Life As Int16 = 1
    'Nome del blocco. Servirà più tardi
    Private _Name As String

    Public Property Life() As Int16
        Get
            Return _Life
        End Get
        Set(ByVal value As Int16)
            _Life = value
        End Set
    End Property

    Public Property Name() As String
        Get
            Return _Name
        End Get
        Set(ByVal value As String)
            _Name = value
        End Set
    End Property

    Sub New()
        MyBase.new()
    End Sub

    Sub New(ByVal Sprite As Texture2D)
        Me.New()
        Me.Sprite = Sprite
        Me.Center = Me.Position + _
            New Vector2(Me.Sprite.Width * Me.Scale / 2, _
            Me.Sprite.Height * Me.Scale / 2)
    End Sub
End Class 
Dato che ci saranno molti blocchi sullo schermo, non è necessario un solo oggetto per rappresentarlo, ma una lista:
'Lista di tutti i blocchi sullo schermo
Private Blocks As New List(Of Block) 
Ed ecco gli sprite che useremo per i blocchi:

Block01


Block02


Block03


Block04


Block05

Le immagini sono chiamate in modo che si possa dedurre la resistenza del blocco dal numero che lo segue: Block03 necessiterà di 3 colpi per essere tolto di mezzo.
Modifichiamo il codice di CollisionCheck in modo che operi anche sui blocchi:
    Private Sub CollisionCheck()
        Dim BallRect As Rectangle = GetBounds(Ball)
        Dim BatRect As Rectangle = GetBounds(Bat)
        'Questa variabile booleana determina se la pallina ha
        'sbattuto contro un blocco. In questo modo, sbattendo
        'contro due blocchi contemporaneamente, i rimbalzi
        'non si annulleranno a vicenda
        Dim Bounced As Boolean = False

        If BallRect.Intersects(BatRect) Then
            CalculateBallVelocity(Bat)
        End If

        If ((Ball.Position.X < 5) Or _
        (Ball.Position.X > Me.GraphicsDevice.Viewport.Width - 5)) _
        And (Ball.Position.Y < Me.GraphicsDevice.Viewport.Height - 5) Then
            Ball.Velocity = _ 
                New Vector2(-Ball.Velocity.X, Ball.Velocity.Y)
        End If

        If Ball.Position.Y < 5 Then
            Ball.Velocity = _ 
                New Vector2(Ball.Velocity.X, -Ball.Velocity.Y)
        End If

        If Ball.Position.Y > Me.Graphics.GraphicsDevice.Viewport.Height Then
            
        End If

        'Questa lista contiene tutti i blocchi distrutti
        Dim HitBlocks As New List(Of Block)
        For Each Block As Block In Blocks
            'Costruisce il rettangolo che contiene il blocco
            Dim BlockRect As Rectangle = GetBounds(Block)
            'Se la palla lo ha colpito e non ha già
            'rimbalzato, procede
            If BallRect.Intersects(BlockRect) And (Not Bounced) Then
                'Inverte la componente Y della velocità
                Ball.Velocity = _ 
                    New Vector2(Ball.Velocity.X, -Ball.Velocity.Y)
                'Imposta Bounced=True
                Bounced = True
                'Toglie un punto vita al blocco
                Block.Life -= 1
                If Block.Life = 0 Then
                    'Se il blocco non ha più vita, lo disabilita
                    'e lo aggiunge alla lista dei blocchi distrutti
                    Block.Enabled = False
                    HitBlocks.Add(Block)
                Else
                    'Altrimenti, cambia il suo sprite, mettendo al
                    'posto di quello attuale, la texture del blocco di
                    'livello minore. Ad esempio, se il blocco giallo
                    'è colpito, diventerà bianco.
                    Block.Sprite = GetTexture("Block" & _
                        Block.Life.ToString.PadLeft(2, "0") & ".png")
                    'La funzione PadLeft fa in modo che il numero
                    'riempia due posti: 1 diventerà 01
                End If
            End If
        Next

        'Rimuove i blocchi distrutti
        For Each Block As Block In HitBlocks
            Blocks.Remove(Block)
        Next
    End Sub 
Per fare una prova, aggiungiamo manualmente qualche blocco in LoadContent:
    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)

        Dim B As Block
        B = New Block(GetTexture("Block01.png"))
        B.Name = "Block01"
        B.Position = New Vector2(150, 150)
        Blocks.Add(B)

        B = New Block(GetTexture("Block02.png"))
        B.Name = "Block02"
        B.Life = 2
        B.Position = New Vector2(400, 300)
        Blocks.Add(B)
    End Sub 
E non dimentichiamoci di disegnarli:
    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)
        'Disegna tutti i blocchi
        For Each Block As GameObject In Blocks
            Block.Draw(Batch)
        Next

        Batch.End()

        MyBase.Draw(gameTime)
    End Sub 
E il risultato è questo.





 

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