• Regolamento Macrocategoria DEV
    Prima di aprire un topic nella Macrocategoria DEV, è bene leggerne il suo regolamento. Sei un'azienda o un hosting/provider? Qui sono anche contenute informazioni per collaborare con Sciax2 ed ottenere l'accredito nella nostra community!

Guida Vb.net & XNA - Game tutorial 3: Movimenti, Input e collisioni

Garu

Utente Attivo
Autore del topic
9 Ottobre 2011
412
0
Miglior risposta
0
Vb.net & XNA - Game tutorial 1: Movimenti, Input e collisioni

Eccoci ad una nuova serie di tutorial per xna e vb.net, questi nuovi tutorial saranno strutturati in maniera diversa,ossia seguiranno passo passo la creazione di piccoli giochi, in maniera molto pratica.

Oggi creeremo un piccolo gioco nel quale impersonando un astronauta alla guida di un'astronave dovremo schivare i meteoriti che ci verranno incontro.

Insomma, un buon esempio per imparare a gestire i movimenti, gli input e le collisioni.

Premessa: La guida è scritta per xna 3.0 - 3.1

Iniziamo!

Inizializzazione


Creiamo un nuovo progetto, applicazione windows form.

Iniziamo subito importando le librerie xna:

Riferimenti -> aggiungi -> .net e cercate xna e xna.framework, in caso non siano presenti potrete trovarle in " C:\Programmi\Microsoft XNA\XNA Game Studio\v3.0\References\Windows\x86\"

1.png



Dopo aver importato le librerie, cancelliamo form1.vb (la form creata automaticamente dal compilatore) e creiamo un nuovo modulo (possiamo chiamarlo come vogliamo).

Facciamo avviare l'applicazione dal nostro modulo e non più dalla form (che non esiste più)

2.png


Nel modulo importiamo le librerie che ci serviranno:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!


E Creiamo il codice per far partire il nostro gioco:


Module XNA_Game_Tutorial1
Sub Main()
Using Game As New Game
Game.Run()
End Using
End Sub
End Module

La classe game contiene il necessario per gestire al meglio il nostro gioco.


Ora passiamo al gioco vero e proprio:


Creiamo la nostra classe principale, creiamo una relazione di eredità con la classe game, creiamo e inizializziamo l'oggetto Graphics che gestirà la nostra scena e le varie impostazioni grafiche, e anche lo spritebatch, che si occuperà del disegno.

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Carichiamo le texture dell'astronave, lo sfondo e per i meteoriti (le immagini si trovano nella stessa cartella del gioco)


Codice:
Perfavore, Entra oppure Registrati per vedere i codici!



Movimento astronave:

Riceviamo l'input da tastiera, utilizzando la classe keyboard state, presente in xna.framework.input

A seconda dei tasti premuti (a o d) cambiamo la posizione dell'astronave.

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Dopo di chè aggiungiamo la funzione al metodo "update" del gioco, che si occupa della logica.


Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Infine disegniamo l'astronave:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!


Il risultato sarà:

3.png




Quindi per adesso il codice completo è il seguente:

Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Graphics
Module XNA_Game_Tutorial1
Sub Main()
Using Game As New Game
Game.Run()
End Using
End Sub
End Module


Public Class Game
Inherits Microsoft.Xna.Framework.Game
Public Graphics As GraphicsDeviceManager
Private Sprite_Batch As SpriteBatch

Sub New()
Graphics = New GraphicsDeviceManager(Me)
Graphics.PreferredBackBufferWidth = 700
Graphics.PreferredBackBufferHeight = 500
Graphics.SynchronizeWithVerticalRetrace = False
IsFixedTimeStep = True
Me.Content.RootDirectory = "content"
End Sub

Protected Overrides Sub Initialize()
Sprite_Batch = New SpriteBatch(Graphics.GraphicsDevice)
MyBase.Initialize()
End Sub

Dim Texture_Asteroide As Texture2D
Dim Texture_Sfondo As Texture2D
Dim Texture_Shuttle As Texture2D
Protected Overrides Sub LoadContent()

Texture_Asteroide = Texture2D.FromFile(Graphics.GraphicsDevice, "Meteora.png")

Texture_Sfondo = Texture2D.FromFile(Graphics.GraphicsDevice, "BackGround.jpg")

Texture_Shuttle = Texture2D.FromFile(Graphics.GraphicsDevice, "Shuttle.png")
Posizione_Astronave = New Vector2(5, 400)

MyBase.LoadContent()

End Sub

Dim Posizione_Astronave As Vector2



Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub


Protected Overrides Sub Update(ByVal GameTime As GameTime)
Comandi()
MyBase.Update(GameTime)

End Sub


Protected Overrides Sub Draw(ByVal gameTime As GameTime)
Graphics.GraphicsDevice.Clear(Color.CornflowerBlue) 'Pulisce La scena


Sprite_Batch.Begin() 'Inizia il disegno

'Disegno dell'immagine dell'astronave, il rectangle contiene la posizone de le dimensioni della nostra immagine
Sprite_Batch.Draw(Texture_Shuttle, New Rectangle(Posizione_Astronave.X, Posizione_Astronave.Y, Texture_Shuttle.Width, Texture_Shuttle.Height), Color.White)


Sprite_Batch.End() 'Fine disegno

Graphics.GraphicsDevice.Present() 'Disegna

MyBase.Draw(gameTime) 'Aggiorna finestra
End Sub

Dim Kbrd As KeyboardState
Private Sub Comandi()
Kbrd = Keyboard.GetState
If Kbrd.IsKeyDown(Keys.A) Then
Posizione_Astronave.X -= 2
ElseIf Kbrd.IsKeyDown(Keys.D) Then
Posizione_Astronave.X += 2
End If
End Sub

Ricapitolando, adesso abbiamo una navicella che si muove su una finestra vuota, quindi aggiungiamoci un bello sfondo stile spazio, abbiamo già caricato la texture quindi basta disegnarla (ovviamente prima di disegnare la navicella)

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Dove il rettangolo parte dal origine della finestra (x0,y0) e si estende per 700 in larghezza e 500 in altezza



Collisioni e generazione asteroidi


Ora viene la parte più complicata, ossia la generazione degli asteroidi e le collisioni.

Dovendo gestire più asteroidi è molto comodo creare un oggetto, visto che abbiamo una sola texture ci basta che l'oggetto abbia come proprietà la sua posizione.

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!


Poi creiamo una lista che conterrà e ci permetterà di gestire e disegnare i meteoriti:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Creiamo una piccola funzione per creare i meteoriti, ci semplificherà il lavoro dopo:

Crea un nuovo oggetto e lo aggiunge alla lista dei meteoriti:
Codice:
Perfavore, Entra oppure Registrati per vedere i codici!


E un altra funzione per generare i meteoriti in maniera casuale, utilizzando la classe random per avere la posizione casuale ovviamente i meteoriti saranno generato dopo un certo intervallo (100).

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!


Ovviamente i meteoriti dovranno muoversi e controllare un eventuale collisione, usando la funzione "intersect" dell'oggetto rectangle possiamo rilevare le collisioni, aggiungiamo il codice al movimento dei meteoriti:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!


Poi ovviamente dovremo disegnare, quindi aggiungiamo il codice per disegnare tutti (leggiamo la lista usando il ciclo for invece del for each perchè dovrebbe essere leggermente più prestante).

Quindi aggiungiamo al codice per il disegno:

Codice:
Perfavore, Entra oppure Registrati per vedere i codici!

Il gioco è ormai completo, il codice completo:

Imports Microsoft.Xna.Framework
Imports Microsoft.Xna.Framework.Input
Imports Microsoft.Xna.Framework.Graphics
Module XNA_Game_Tutorial1
Sub Main()
Using Game As New Game
Game.Run()
End Using
End Sub
End Module


Public Class Game
Inherits Microsoft.Xna.Framework.Game
Public Graphics As GraphicsDeviceManager
Private Sprite_Batch As SpriteBatch

Sub New()
Graphics = New GraphicsDeviceManager(Me)
Graphics.PreferredBackBufferWidth = 700
Graphics.PreferredBackBufferHeight = 500
Graphics.SynchronizeWithVerticalRetrace = False
IsFixedTimeStep = True
Me.Content.RootDirectory = "content"
End Sub

Protected Overrides Sub Initialize()
Sprite_Batch = New SpriteBatch(Graphics.GraphicsDevice)
MyBase.Initialize()
End Sub

Dim Texture_Asteroide As Texture2D
Dim Texture_Sfondo As Texture2D
Dim Texture_Shuttle As Texture2D
Protected Overrides Sub LoadContent()

Texture_Asteroide = Texture2D.FromFile(Graphics.GraphicsDevice, "Meteora.png")

Texture_Sfondo = Texture2D.FromFile(Graphics.GraphicsDevice, "BackGround.jpg")

Texture_Shuttle = Texture2D.FromFile(Graphics.GraphicsDevice, "Shuttle.png")
Posizione_Astronave = New Vector2(5, 400)

MyBase.LoadContent()

End Sub

Dim Posizione_Astronave As Vector2



Protected Overrides Sub UnloadContent()
MyBase.UnloadContent()
End Sub


Protected Overrides Sub Update(ByVal GameTime As GameTime)
Comandi()
Generazione_Random()
Muovi_Meteoriti()

MyBase.Update(GameTime)

End Sub


Protected Overrides Sub Draw(ByVal gameTime As GameTime)
Graphics.GraphicsDevice.Clear(Color.CornflowerBlue) 'Pulisce La scena


Sprite_Batch.Begin() 'Inizia il disegno

Sprite_Batch.Draw(Texture_Sfondo, New Rectangle(0, 0, 700, 500), Color.White)

For i = 0 To Lista_Meteoriti.Count - 1
Sprite_Batch.Draw(Texture_Asteroide, New Rectangle(Lista_Meteoriti(i).Posizione.X, Lista_Meteoriti(i).Posizione.Y, Texture_Asteroide.Width, Texture_Asteroide.Height), Color.White)
Next

'Disegno dell'immagine dell'astronave, il rectangle contiene la posizone de le dimensioni della nostra immagine
Sprite_Batch.Draw(Texture_Shuttle, New Rectangle(Posizione_Astronave.X, Posizione_Astronave.Y, Texture_Shuttle.Width, Texture_Shuttle.Height), Color.White)


Sprite_Batch.End() 'Fine disegno

Graphics.GraphicsDevice.Present() 'Disegna

MyBase.Draw(gameTime) 'Aggiorna finestra
End Sub

Dim Kbrd As KeyboardState
Private Sub Comandi()
Kbrd = Keyboard.GetState
If Kbrd.IsKeyDown(Keys.A) Then
Posizione_Astronave.X -= 2
ElseIf Kbrd.IsKeyDown(Keys.D) Then
Posizione_Astronave.X += 2
End If
End Sub

Private Sub Muovi_Meteoriti()
For i = 0 To Lista_Meteoriti.Count - 1
Lista_Meteoriti(i).Posizione = New Vector2(Lista_Meteoriti(i).Posizione.X, Lista_Meteoriti(i).Posizione.Y + 1)

If New Rectangle(Posizione_Astronave.X, Posizione_Astronave.Y, Texture_Shuttle.Width, Texture_Shuttle.Height).Intersects(New Rectangle(Lista_Meteoriti(i).Posizione.X, Lista_Meteoriti(i).Posizione.Y, Texture_Asteroide.Width, Texture_Asteroide.Height)) Then
MsgBox("Sei Morto") 'Se l'astronave tocca un asteroide allora h
End
End If

Next
End Sub



Dim Lista_Meteoriti As New List(Of Meteorite)
Private Sub Genera_Meteorite(ByVal Posizione As Vector2)
Dim M As New Meteorite
With M
.Posizione = Posizione
End With
Lista_Meteoriti.Add(M)
End Sub


Dim rnd As New Random
Dim LastGen As Integer
Private Sub Generazione_Random()
LastGen += 1

If LastGen >= 100 Then
LastGen = 0

Dim V As New Vector2(rnd.Next(0, 700), 0) 'Genera il meteorite in una posizione casuale sull'asse X
Genera_Meteorite(V)

End If
End Sub

Public Class Meteorite

Dim _Posizione As Vector2
Public Property Posizione As Vector2
Get
Return _Posizione
End Get
Set(ByVal value As Vector2)
_Posizione = value
End Set
End Property

End Class

End Class

Il risultato finale:

4.png



Ecco il download del progetto completo:
Perfavore, Entra oppure Registrati per vedere i Link!





Al momento del debug potrebbe essere visualizzato il seguente errore: "L'assembly in modalità mista è compilato in base alla versione 'v2.0.50727' del runtime e non può essere caricato nel runtime 4.0 senza ulteriori informazioni di configurazione." in questo caso dovrete cambiare il framework di compilazione dell'applicazione alla versione 3.5 (o inferiore) Andando in compilazione -> Opzioni di compilazione avanzate
 
Ultima modifica:
Riferimento: Vb.net & XNA - Game tutorial 3: Movimenti, Input e collisioni

Davvero ottima questa guida, in tutti i sensi! :emoji_slight_smile:
 
Riferimento: Vb.net & XNA - Game tutorial 3: Movimenti, Input e collisioni

Ottima! Continua così! :emoji_slight_smile:
 
Riferimento: Vb.net & XNA - Game tutorial 3: Movimenti, Input e collisioni

Grazie a tutti, se avete richieste specifiche vedrò di accontentarvi, se non ci sono richieste dovrei parlare di alcune tecniche di ottimizzazione.
 
Riferimento: Vb.net & XNA - Game tutorial 3: Movimenti, Input e collisioni

Ti ringrazio Garu, è sempre un piacere vedere post con nuove cose e soprattutto che parlano del Framework XNA ( non so come mai ma l'ho preso in simpatia :emoji_smiley: ); vedo anche che hai commentato il codice come ti avevo suggerito nelle discussioni precedenti...ottimo :emoji_slight_smile: Se continuassi così potrebbe uscire un decente tutorial sul Framework XNA.

Grazie a tutti, se avete richieste specifiche vedrò di accontentarvi

Io ho una richiesta : mi regali 5 euro ? :emoji_smiley:
 
Ultima modifica: