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\"
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ù)
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à:
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
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
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:
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: