Introduzione
In questa serie di articoli vedremo come creare un gioco completo in XNA, in cui verranno forniti indicazioni di un ciclo completo di un gioco, come la stesura di un gioco, ambiente, punteggio, e collisione.
L’esempio sarà un’astronave che deve evitare degli ostacoli nello spazio, che sono degli astereoidi inoltre può sparare per distruggere tali oggetti.
Creazione del video gioco
Si deve creare un nuovo progetto XNA, questo progetto, nel corso del tutorial, verrà implementato con classi, progetti ed oggetti. Il nome è a scelta libera (nel nostro caso è XNATutorial)
Aggiungiamo alla sezione “Content” un immagine che riguarda una navicella spaziale, per esempio simile a quella illustrata in figura 1.
Figura 1
Creazione della classe player
Si aggiunge al progetto una nuova classe (tasto destro sul progetto in esplora soluzione) e selezioniamo la voce di menu “Aggiungi” e successivamente “Classe”.
La classe la chiameremo “Player” il nome del file sarà “Player.cs”.
Questa classe, avrà il compito di gestire le informazioni del nostro oggetto “immagine” come posizione, lo stato, il carburante e tanto altro.
Qui di seguito si riporta il codice completo di tale classe.
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//per la classe texture2d
using Microsoft.Xna.Framework.Graphics;
//per la classe Vector2
using Microsoft.Xna.Framework;
namespace XNATutorial
{
class Player
{
// per gestire l'oggetto
public Texture2D PlayerTexture;
// per la posizione
public Vector2 Posizione;
// stato
public bool StatoAttivo;
// totale carburante
public int Carburante;
//larghezza per il posizionamento
public int Width
{
get { return PlayerTexture.Width; }
}
//altezza per il posizionamento
public int Height
{
get { return PlayerTexture.Height; }
}
public void Initialize(Texture2D texture, Vector2 posizione)
{
PlayerTexture = texture;
// imposto la posizione
Posizione = posizione;
//imposto lo stato in true quindi attivo
StatoAttivo = true;
//imposto il punteggio
Carburante = 100;
}
public void Update()
{
}
/// <summary>
/// Funzione che permette di visualizzare a video il risultato
/// </summary>
/// <param name="spriteBatch"></param>
public void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(PlayerTexture, Posizione, null, Color.White, 0f, Vector2.Zero, 1f, SpriteEffects.None, 0f);
}
}
}
La classe contiene tre metodi, initialize, che imposta i parametri della classe, il metodo draw, che ridisegna il nostro oggetto a video, e update (che vedremo più avanti), inoltre avremmo vari oggetti, per gestire la posizione, il carburante, il disegno e tanto altro.
Passiamo alla classe, game1, per impostare il nostro gioco.
Impostare la classe Game1
Si creano a livello di classe, gli oggetti che permettono di gestire le informazioni del gioco, come un oggetto della classe creata precedentemente, la velocità, la gestione della tastiera, qui di seguito si riporta tali dichiarazioni
//oggetto della classe Player
Player player;
//Per la gestioe della tastiera
KeyboardState StatoCorrenteTastiera;
KeyboardState StatoPrecedenteTastiera;
// la velocità di spostamento
float VelocitaSpostamento;
Nell’evento initialize, inizializziamo l’oggetto player ed impostiamo la velocità di spostamento, il tutto come illustrato qui di seguito.
protected override void Initialize()
{
// TODO: Add your initialization logic here
// inizializzo la classe
player = new Player();
//imposola velocità
VelocitaSpostamento = 8.0f;
base.Initialize();
}
Passiamo all’evento loadContent, in cui andremo a rilevare la risorsa (immagine dell’astronave) da visualizzare a video e la relativa posizione.
In questo evento, utilizziamo il metodo Initialize, creato precedentemente nella classe player, in cui andremo ad inserire la risorsa (immagine) e la posizione.
Qui di seguito si riporta il codice completo delle suddette operazioni.
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// carico la risorsa (immagine)
Vector2 playerPosizione = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
player.Initialize(Content.Load<Texture2D>("Astronave"), playerPosizione);
// TODO: use this.Content to load your game content here
}
Si crea un metodo che permette di gestire l’input della tastiera, come la pressione dei tasti di freccia di direzione (freccette) per lo spostamento della nostra immagine, il metodo denominato UpdatePlayer, viene riportato qui di seguito.
private void UpdatePlayer(GameTime gameTime)
{
//nel caso che digito il pulsante esc esco dal gioco
if (StatoCorrenteTastiera.IsKeyDown(Keys.Escape))
base.Exit();
//in riferimento alle freccie della tastiera sposto l'astronave
if (StatoCorrenteTastiera.IsKeyDown(Keys.Left) )
{
player.Posizione.X -= VelocitaSpostamento;
}
if (StatoCorrenteTastiera.IsKeyDown(Keys.Right) )
{
player.Posizione.X += VelocitaSpostamento;
}
if (StatoCorrenteTastiera.IsKeyDown(Keys.Up) )
{
player.Posizione.Y -= VelocitaSpostamento;
}
if (StatoCorrenteTastiera.IsKeyDown(Keys.Down) )
{
player.Posizione.Y += VelocitaSpostamento;
}
//imposto la posizione della navicella
player.Posizione.X = MathHelper.Clamp(player.Posizione.X, 0, GraphicsDevice.Viewport.Width - player.Width);
player.Posizione.Y = MathHelper.Clamp(player.Posizione.Y, 0, GraphicsDevice.Viewport.Height - player.Height);
}
Nel metodo update, della classe game1, rileviamo lo stato della tastiera precedente e quello in cui si è appena fatto click, per poi eseguire il metodo “UpdatePlayer” creato poco fa.
Qui di seguito si riporta il codice dell’evento update.
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
//tasto precedente prima di questa modifica
StatoPrecedenteTastiera = StatoCorrenteTastiera;
//rilevo l'ultimo pulsante digitato
StatoCorrenteTastiera = Keyboard.GetState();
//Update the player
UpdatePlayer(gameTime);
base.Update(gameTime);
}
L’evento Draw, permette di ridisegnare a video le varie “attività”, in particolare, utilizziamo il metodo Draw, per ridisegnare il gioco, il metdo beging abilita la modifica a video, mentre end la chiusura
Qui di seguito si riporta il codice dell’evento Draw
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
// TODO: Add your drawing code here
//ridisegno il tutto
spriteBatch.Begin();
//aggiorno la visualizzazione
player.Draw(spriteBatch);
//termine del ridisegno
spriteBatch.End();
base.Draw(gameTime);
}
Qui di seguito si riporta il codice completo della classe games
using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;
namespace XNATutorial
{
/// <summary>
/// This is the main type for your game
/// </summary>
public class Game1 : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
//oggetto della classe Player
Player player;
//Per la gestione della tastiera
KeyboardState StatoCorrenteTastiera;
KeyboardState StatoPrecedenteTastiera;
// la velocità di spostamento
float VelocitaSpostamento;
public Game1()
{
graphics = new GraphicsDeviceManager(this);
Content.RootDirectory = "Content";
}
/// <summary>
/// Allows the game to perform any initialization it needs to before starting to run.
/// This is where it can query for any required services and load any non-graphic
/// related content. Calling base.Initialize will enumerate through any components
/// and initialize them as well.
/// </summary>
protected override void Initialize()
{
// TODO: Add your initialization logic here
// inizializzo la classe
player = new Player();
//imposto la velocità
VelocitaSpostamento = 8.0f;
base.Initialize();
}
/// <summary>
/// LoadContent will be called once per game and is the place to load
/// all of your content.
/// </summary>
protected override void LoadContent()
{
// Create a new SpriteBatch, which can be used to draw textures.
spriteBatch = new SpriteBatch(GraphicsDevice);
// carico la risorsa (immagine)
Vector2 playerPosizione = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
player.Initialize(Content.Load<Texture2D>("Astronave"), playerPosizione);
// TODO: use this.Content to load your game content here
}
/// <summary>
/// UnloadContent will be called once per game and is the place to unload
/// all content.
/// </summary>
protected override void UnloadContent()
{
// TODO: Unload any non ContentManager content here
}
/// <summary>
/// Allows the game to run logic such as updating the world,
/// checking for collisions, gathering input, and playing audio.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Update(GameTime gameTime)
{
// Allows the game to exit
if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed)
this.Exit();
// TODO: Add your update logic here
//tasto precedente prima di questa modifica
StatoPrecedenteTastiera = StatoCorrenteTastiera;
//rilevo l'ultimo pulsante digitato
StatoCorrenteTastiera = Keyboard.GetState();
//Update the player
UpdatePlayer(gameTime);
base.Update(gameTime);
}
private void UpdatePlayer(GameTime gameTime)
{
//nel caso che digito il pulsante esc esco dal gioco
if (StatoCorrenteTastiera.IsKeyDown(Keys.Escape))
base.Exit();
//in riferimento alle freccie della tastiera sposto l'astronave
if (StatoCorrenteTastiera.IsKeyDown(Keys.Left) )
{
player.Posizione.X -= VelocitaSpostamento;
}
if (StatoCorrenteTastiera.IsKeyDown(Keys.Right) )
{
player.Posizione.X += VelocitaSpostamento;
}
if (StatoCorrenteTastiera.IsKeyDown(Keys.Up) )
{
player.Posizione.Y -= VelocitaSpostamento;
}
if (StatoCorrenteTastiera.IsKeyDown(Keys.Down) )
{
player.Posizione.Y += VelocitaSpostamento;
}
//imposto la posizione della navicella
player.Posizione.X = MathHelper.Clamp(player.Posizione.X, 0, GraphicsDevice.Viewport.Width - player.Width);
player.Posizione.Y = MathHelper.Clamp(player.Posizione.Y, 0, GraphicsDevice.Viewport.Height - player.Height);
}
/// <summary>
/// This is called when the game should draw itself.
/// </summary>
/// <param name="gameTime">Provides a snapshot of timing values.</param>
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.White);
// TODO: Add your drawing code here
//ridisegno il tutto
spriteBatch.Begin();
//aggiorno la visualizzazione
player.Draw(spriteBatch);
//termine del ridisegno
spriteBatch.End();
base.Draw(gameTime);
}
}
}
Figura 2
Conclusioni
Ora non ci resta che compilare il nostro gioco ed una volta avviata l’applicazione, utilizzando le frecce della tastiere, vedremo la nostra astronave spostarsi il tutto come mostrato in figura 2.
Questa prima parte del tutorial ha voluto fornire le basi per la gestione delle risorse (immagine) ed il relativo spostamento.