lunedì 4 giugno 2012

Tutorial XNA creazione di un video gioco completo parte 5

Si riporta l'articolo scritto per il sito http://www.iprogrammatori.it/articoli/programmazione/art_tutorial-xna-creazione-di-un-gioco-compl_1169.aspx

Introduzione

In questa parte, vedremo come gestire la collisione con gli ostacoli e la possibilità di dotare la nostra risorsa, o meglio l’astronave di un laser, che permette di distruggere gli ostacoli che incontra in volo.
Aggiungiamo alla sezione “Content” la risorsa immagine che riguarda il fuoco della nostra navicella.
Dalla finestra Esplora soluzione, selezioniamo dal menu di scelta rapida, la voce “Aggiungi” e dopo il sottomenu “Elemento esistente”
Un esempio può essere la figura 1.


Figura 1

Creazione di una classe per il fuoco

Ora non ci resta che creare una classe per la gestione dell’arma , la classe la chiamamo “Sparo”, dalla finestra di Esplora soluzione, facciamo click tramite tasto destro sul nome del progetto, e selezioniamo la voce, “Aggiungi” nel menu che viene aperto, selezioniamo la voce di menu “Classe”. Assegniamo il nome “Sparo.cs”.
Inseriamo lo spazio dei nomi, per gestire la classe Texture2d e Vector2. Qui di seguito si riporta il frammento di codice.

//per la gestione della classe Texture2d
using Microsoft.Xna.Framework.Graphics;
//per la classe Vector2
using Microsoft.Xna.Framework;
Come nelle precedenti classi, dobbiamo creare dei membri che permettono di gestire la risorsa, la velocità della risorsa, larghezza, altezza ed altro ancora.
Inoltre, i tre metodi fondamentali, come il metodo Initialize per inizializzare le variabili, il metodo update, per l’aggiornamento delle informazioni, ed il metodo “Draw” per la visualizzazione della risorsa.
Si riporta il codice delle suddette operazioni.
//Gestione della risorsa per il fuoco
        public Texture2D TextureFuoco;

        //posizione della risorsa nello schermo
        public Vector2 Posizione;

        //Lo statoattivo
        public bool StatoAttivo;

        //valore relativo al danno recato agli asteroidi
        public int Danno;

        // riquadro di visualizzazione
        Viewport Viewport;

        //larghezza
        public int Width
        {
            get { return TextureFuoco.Width; }
        }

        //alterzza
        public int Height
        {
            get { return TextureFuoco.Height; }
        }

        //velocita di spostamento fuoco
        float VelocitaFuoco;


        public void Initialize()
        {
        }
        public void Update()
        {
        }
        public void Draw()
        {
        }

Modifichiamo il metodo Initialize, in cui andremo ad impostare il codice per la valorizzazione delle variabili.
Qui di seguito si riporta il codice relativo al metodo Initialize.

public void Initialize(Viewport viewport, Texture2D texture, Vector2 posizione)
        {
            TextureFuoco = texture;
            Posizione = posizione;
            this.Viewport = viewport;

            StatoAttivo = true;

            Danno = 2;

            VelocitaFuoco = 20f;
        }

Modifichiamo il metodo update, impostando lo spostamento della risorsa di tipo fuoco, che va da sinistra destra, e nel caso che la posizione nello schermo è stata superata, togliere la visualizzazione.
Si riporta il codice del metodo update.

public void Update()
        {
            //Permette lo spostamento del fuoco da sinistra a destra, incremendo la posizione tramite la velocita
            Posizione.X += VelocitaFuoco;

            //verifico se stiamo nell'area per la visualizzazione del fuoco
            if (Posizione.X + TextureFuoco.Width / 2 > Viewport.Width)
                StatoAttivo = false;

        }

Il metodo “Draw”, permetterà la visualizzazione della risorsa a video.
Qui di seguito il codice del metodo “Draw”.

public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(TextureFuoco, Posizione, null, Color.White, 0f,new Vector2(Width / 2, Height / 2), 1f, SpriteEffects.None, 0f);

        }
Si riporta il codice completo della classe sparo.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
//per la gestione della classe Texture2d
using Microsoft.Xna.Framework.Graphics;
//per la classe Vector2
using Microsoft.Xna.Framework;

namespace XNATutorial
{
    class Sparo
    {

        //Gestione della risorsa per il fuoco
        public Texture2D TextureFuoco;

        //posizione della risorsa nello schermo
        public Vector2 Posizione;

        //Lo statoattivo
        public bool StatoAttivo;

        //valore relativo al danno recato agli asteroidi
        public int Danno;

        // riquadro di visualizzazione
        Viewport Viewport;

        //larghezza
        public int Width
        {
            get { return TextureFuoco.Width; }
        }

        //alterzza
        public int Height
        {
            get { return TextureFuoco.Height; }
        }

        //velocita di spostamento fuoco
        float VelocitaFuoco;


        public void Initialize(Viewport viewport, Texture2D texture, Vector2 posizione)
        {
            TextureFuoco = texture;
            Posizione = posizione;
            this.Viewport = viewport;

            StatoAttivo = true;

            Danno = 2;

            VelocitaFuoco = 20f;
        }
        public void Update()
        {
            //Permette lo spostamento del fuoco da sinistra a destra, incremendo la posizione tramite la velocita
            Posizione.X += VelocitaFuoco;

            //verifico se stiamo nell'area per la visualizzazione del fuoco
            if (Posizione.X + TextureFuoco.Width / 2 > Viewport.Width)
                StatoAttivo = false;

        }
        public void Draw(SpriteBatch spriteBatch)
        {
            spriteBatch.Draw(TextureFuoco, Posizione, null, Color.White, 0f,new Vector2(Width / 2, Height / 2), 1f, SpriteEffects.None, 0f);

        }



    }
}

Classe Game1

Ora passiamo alla classe Game1, dove andremo a gestire la nuova classe e la risorsa fuoco, precedentemente aggiunta.
Si creano a livello di classe, dei membri per la gestione della classe “Sparo”.
Qui di seguito si riporta i membri per la gestione del tempi tra uno sparo e l’altro, per la gestione della risorsa,  e la classe sparo.

//per la gestione della risorsa fuoco
            Texture2D TextureFuoco;
            List<Sparo> spari;

            //per la gestione dei tempi tra uno sparo e l'altro
            TimeSpan TimePrimoFuoco;
            TimeSpan TimeFuocoPrecedente;
Nell’evento “Inizitialize” impostiamo i vari oggetti.
//inizializzo l'oggetto per la gestione del fuoco, i vari spari
            spari = new List<Sparo>();

            //imposto il tempo del primo fuoco
            TimePrimoFuoco = TimeSpan.FromSeconds(.15f);


Nell’evento “LoadContent”, scriviamo il codice, che permette di caricare la risorsa.
Tramite il metodo Load, della classe Content, impostiamo l’oggetto TextureFuoco con la risorsa inserita nel content.
Qui di seguito il codice di tali operazioni con il codice completo dell’evento “LoadContent”.

protected override void LoadContent()
        {
            // Create a new SpriteBatch, which can be used to draw textures.
            spriteBatch = new SpriteBatch(GraphicsDevice);
            //oggetto per la gestione dell'effetto immagini in movimento
            Animazione playerAnimazione = new Animazione();
            Texture2D playerTexture = Content.Load<Texture2D>("AstronaveMovimento");
            playerAnimazione.Initialize(playerTexture, Vector2.Zero, 115, 69, 8, 30, Color.White, 1f, true);

            // carico la risorsa (immagine)
            Vector2 playerPosizione = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
           //ricambio l'oggetto player
            player.Initialize(playerAnimazione, playerPosizione);
            // player.Initialize(Content.Load<Texture2D>("Astronave"), playerPosizione);


            //carico le immagini
            sfondo1.Initialize(Content, "Sfondo1", GraphicsDevice.Viewport.Width, -1);
            sfondo2.Initialize(Content, "Sfondo2", GraphicsDevice.Viewport.Width, -2);

            SfondoPrincipale = Content.Load<Texture2D>("SfondoPriincipale");
            //carico l'immagine asteroide
            AsteroideTexture = Content.Load<Texture2D>("asteroide");
            //carico l'immagine relativo al fuoco
            TextureFuoco = Content.Load<Texture2D>("Fuoco");
            // TODO: use this.Content to load your game content here
        }

Ora non ci resta che creare il metodo per l’aggiunta del fuoco nella nostra area.

//metodo che permette di gestire l'aggiunta di risorse nello area di gioco
        private void AggiungiFuoco(Vector2 posizione)
        {
            Sparo sparo = new Sparo();
            sparo.Initialize(GraphicsDevice.Viewport, TextureFuoco, posizione);
            spari.Add(sparo);
        }

Modifichiamo il metodo “UpdatePlayer” per la gestione del fuoco, utilizzando il metodo poco fa creato.
Si riporta il metodo “UpdatePlayer”, con la modifica indicata.


private void UpdatePlayer(GameTime gameTime)
        {
            //passo l'oggetto gametime
            player.Update(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 + 50);
            //verifico l'intervallo di tempo tra un fuoco e l'altro
            if (gameTime.TotalGameTime - TimeFuocoPrecedente > TimePrimoFuoco)
            {
                //imposto il tempo
                TimeFuocoPrecedente = gameTime.TotalGameTime;

                // agguingo una risorsa a video, in questo modo viene inserito un oggetto di tipo fuoco
                AggiungiFuoco(player.Posizione + new Vector2(player.Width / 2, 0));
            }
        }

Si crea una funzione che permette di gestire la collisione , questo metodo verrà utilizzato per gestire le due risorse, asteroide e fuoco.
Si riporta il codice completo del metodo collisione.


//per la gestione della collissione
        private void Collisione()
        {
            // determiniamo l'area degli oggetti
            Rectangle rectangleArea1;
            Rectangle rectangleArea2;

            //area per definire la posizione degli oggetti
            rectangleArea1 = new Rectangle((int)player.Posizione.X,
            (int)player.Posizione.Y,
            player.Width,
            player.Height);
            //collisione per asteroide e navicella
            for (int i = 0; i < Asteroidi.Count; i++)
            {
                rectangleArea2 = new Rectangle((int)Asteroidi[i].Posizione.X,
                (int)Asteroidi[i].Posizione.Y,
                Asteroidi[i].Width,
                Asteroidi[i].Height);

                // Determina la collissione tra i due oggietti
                if (rectangleArea1.Intersects(rectangleArea2))
                {
                    //danni all'astronave
                    player.Carburante -= Asteroidi[i].DanniAstronave;

                    // energia
                    Asteroidi[i].Energia = 0;

                    //cambio lo stato attivo nel caso che ho finito il carburante
                    if (player.Carburante <= 0)
                        player.StatoAttivo = false;
                }

            }

            //Collisione tra il fuoco ed asteroide
            for (int i = 0; i < spari.Count; i++)
            {
                for (int j = 0; j < Asteroidi.Count; j++)
                {
                    //Creo e verifico e se le aree sono in collissioni
                    rectangleArea1 = new Rectangle((int)spari[i].Posizione.X -
                    spari[i].Width / 2, (int)spari[i].Posizione.Y -
                    spari[i].Height / 2, spari[i].Width, spari[i].Height);

                    rectangleArea2 = new Rectangle((int)Asteroidi[j].Posizione.X - Asteroidi[j].Width / 2,
                    (int)Asteroidi[j].Posizione.Y - Asteroidi[j].Height / 2,
                    Asteroidi[j].Width, Asteroidi[j].Height);

                    // Determina la collissione tra i due oggietti
                    if (rectangleArea1.Intersects(rectangleArea2))
                    {
                         
                        Asteroidi[j].Energia -= spari[i].Danno;
                        spari[i].StatoAttivo = false;
                    }
                }
            }

        }

Nel metodo Update scriviamo l’invocazione di questo metodo, subito dopo quello di aggiornaAsteroide
Si crea una funzione, che permette di aggiornare la visualizzazione a video delle varie immagini, eliminandole.
Qui di seguito si riporta la funzione per la gestione della visualizzazione delle immagini.


//permette di togliere gli oggetti in visualizzazione
        private void AggiornaFuoco()
        {
            //se lo stato non è attivo, elimina dall'area di visualizzazione la risorsa
            for (int i = spari.Count - 1; i >= 0; i--)
            {
                spari[i].Update();

                if (spari[i].StatoAttivo == false)
                {
                    spari.RemoveAt(i);
                }
            }
        }

Nel metodo Update, dopo la riga di codice riguardante l’invocazione del metodo della collisione, inseriamo il codice che richiama la funzione poco fa creata.
Si riporta il codice del metodo “Update”.

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();
            //aggiorno il gaming
            UpdatePlayer(gameTime);
            //aggiorno la posizione delle immagini
            sfondo1.Update();
            sfondo2.Update();
            //aggiungo o elimino gli asteroidi
            AggiornaAsteroidi(gameTime);
            //per la collisione
            Collisione();
            //per la visualizzazione
            AggiornaFuoco();
            //elimino
            base.Update(gameTime);
        }

Nel metodo “Draw” scriviamo il codice per la gestione grafica della risorsa fuoco, subito dopo quella relativo alla gestione dell’asteroide.
Si riporta il codice completo dellìevento “Draw”.

protected override void Draw(GameTime gameTime)
        {
            GraphicsDevice.Clear(Color.White);
            // TODO: Add your drawing code here
            //ridisegno il tutto
            spriteBatch.Begin();

            spriteBatch.Draw(SfondoPrincipale, Vector2.Zero, Color.White);

            //visualizzo lo spostamento
            sfondo1.Draw(spriteBatch);
            sfondo2.Draw(spriteBatch);
            //aggiorno la visualizzazione della risorsa di tipo asteroide
            for (int i = 0; i < Asteroidi.Count; i++)
            {
                Asteroidi[i].Draw(spriteBatch);
            }
            //aggiorno la visualizzazione della risora di tipo fuoco
            for (int i = 0; i < spari.Count; i++)
            {
                spari[i].Draw(spriteBatch);
            }

            //aggiorno la visualizzazione
            player.Draw(spriteBatch);
            //termine del ridisegno
            spriteBatch.End();
            base.Draw(gameTime);
        }

Si riporta il codice completo della classe Game1.

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;


        //immagine principale
        Texture2D SfondoPrincipale;

        //gestione delle immagini di sfondo quelle in movimento
        Sfondo sfondo1;
        Sfondo sfondo2;
        //gestione della risorsa asteroide
        //oggetto di tipo Asteroide
        Texture2D AsteroideTexture;
        List<Asteroide> Asteroidi;


        //oggetti per gestire i tempi di visualizzare gli asteroidi
        TimeSpan TempoAsteroide;
        TimeSpan TempoAsteroidePrecedente;


        //numero causale per la visualizzazione degli asteroide
        Random random;
        //per la gestione della risorsa fuoco
        Texture2D TextureFuoco;
        List<Sparo> spari;

        //per la gestione dei tempi tra uno sparo e l'altro
        TimeSpan TimePrimoFuoco;
        TimeSpan TimeFuocoPrecedente;
        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();
            //imposola velocità
            VelocitaSpostamento = 8.0f;
            //oggetti per la gestione dello sfondo
            sfondo1 = new Sfondo();
            sfondo2 = new Sfondo();
            //inizializzo l'oggetto degli asteroide
            Asteroidi = new List<Asteroide>();
           
            //imposto a zero il tempo per asteroide precendente
            TempoAsteroidePrecedente = TimeSpan.Zero;

            //imposto i tempi degli asteroide
            TempoAsteroide = TimeSpan.FromSeconds(1.0f);

            //inizializzo l'oggetto di tipo random
            random = new Random();
            //inizializzo l'oggetto per la gestione del fuoco, i vari spari
            spari = new List<Sparo>();

            //imposto il tempo del primo fuoco
            TimePrimoFuoco = TimeSpan.FromSeconds(.15f);


            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);
            //oggetto per la gestione dell'effetto immagini in movimento
            Animazione playerAnimazione = new Animazione();
            Texture2D playerTexture = Content.Load<Texture2D>("AstronaveMovimento");
            playerAnimazione.Initialize(playerTexture, Vector2.Zero, 115, 69, 8, 30, Color.White, 1f, true);

            // carico la risorsa (immagine)
            Vector2 playerPosizione = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.X, GraphicsDevice.Viewport.TitleSafeArea.Y + GraphicsDevice.Viewport.TitleSafeArea.Height / 2);
           //ricambio l'oggetto player
            player.Initialize(playerAnimazione, playerPosizione);
            // player.Initialize(Content.Load<Texture2D>("Astronave"), playerPosizione);


            //carico le immagini
            sfondo1.Initialize(Content, "Sfondo1", GraphicsDevice.Viewport.Width, -1);
            sfondo2.Initialize(Content, "Sfondo2", GraphicsDevice.Viewport.Width, -2);

            SfondoPrincipale = Content.Load<Texture2D>("SfondoPriincipale");
            //carico l'immagine asteroide
            AsteroideTexture = Content.Load<Texture2D>("asteroide");
            //carico l'immagine relativo al fuoco
            TextureFuoco = Content.Load<Texture2D>("Fuoco");
            // 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();
            //aggiorno il gaming
            UpdatePlayer(gameTime);
            //aggiorno la posizione delle immagini
            sfondo1.Update();
            sfondo2.Update();
            //aggiungo o elimino gli asteroidi
            AggiornaAsteroidi(gameTime);
            //per la collisione
            Collisione();
            //per la visualizzazione
            AggiornaFuoco();
            //elimino
            base.Update(gameTime);
        }


        private void UpdatePlayer(GameTime gameTime)
        {
            //passo l'oggetto gametime
            player.Update(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 + 50);
            //verifico l'intervallo di tempo tra un fuoco e l'altro
            if (gameTime.TotalGameTime - TimeFuocoPrecedente > TimePrimoFuoco)
            {
                //imposto il tempo
                TimeFuocoPrecedente = gameTime.TotalGameTime;

                // agguingo una risorsa a video, in questo modo viene inserito un oggetto di tipo fuoco
                AggiungiFuoco(player.Posizione + new Vector2(player.Width / 2, 0));
            }
        }
        //permette di togliere gli oggetti in visualizzazione
        private void AggiornaFuoco()
        {
            //se lo stato non è attivo, elimina dall'area di visualizzazione la risorsa
            for (int i = spari.Count - 1; i >= 0; i--)
            {
                spari[i].Update();

                if (spari[i].StatoAttivo == false)
                {
                    spari.RemoveAt(i);
                }
            }
        }



        private void AggiungiAsteroide()
        {
            // Create the animation object
            Animazione AsteroideAnimazione = new Animazione();

            //Inizializzo l'oggetto per la gestione dell'animazione dell'asteroide - possiamo creare anche un immagini con più immagine animate, cambiando il valore 1 con il totale degli elementi
            AsteroideAnimazione.Initialize(AsteroideTexture, Vector2.Zero, 47, 61, 1, 30, Color.White, 1f, true);

            //genero in maniera causale la posizione della risorsa nello schermo
            Vector2 posizione = new Vector2(GraphicsDevice.Viewport.Width + AsteroideTexture.Width / 2, random.Next(100, GraphicsDevice.Viewport.Height - 100));

            //Creo un nuovo asteroide
            Asteroide asteroide = new Asteroide();

            //inzializzo con l'oggetto animazione e posizione
            asteroide.Initialize(AsteroideAnimazione, posizione);

            //aggiungo il nuovo oggetto alla lista degli oggetti di tipo asteroidei
            Asteroidi.Add(asteroide);
        }
        //metodo che permette di gestire l'aggiunta di risorse nello area di gioco
        private void AggiungiFuoco(Vector2 posizione)
        {
            Sparo sparo = new Sparo();
            sparo.Initialize(GraphicsDevice.Viewport, TextureFuoco, posizione);
            spari.Add(sparo);
        }




        /// <summary>
        /// funzione che permette di aggiungere o eliminare le risorse da visualizzare a video
        /// </summary>
        /// <param name="gameTime"></param>
        private void AggiornaAsteroidi(GameTime gameTime)
        {
            //aggiungo un nuovo elemento ogni secondo e mezzo.
            if (gameTime.TotalGameTime - TempoAsteroidePrecedente > TempoAsteroide)
            {
                TempoAsteroidePrecedente = gameTime.TotalGameTime;

                //aggiungo la risorsa a video
                AggiungiAsteroide();
            }

            //nel caso che lo stato attivo è false elimino l'asteroide in questione
            for (int i = Asteroidi.Count - 1; i >= 0; i--)
            {
                Asteroidi[i].Update(gameTime);

                if (Asteroidi[i].StatoAttivo == false)
                {
                    Asteroidi.RemoveAt(i);
                }
            }
        }

//per la gestione della collissione
        private void Collisione()
        {
            // determiniamo l'area degli oggetti
            Rectangle rectangleArea1;
            Rectangle rectangleArea2;

            //area per definire la posizione degli oggetti
            rectangleArea1 = new Rectangle((int)player.Posizione.X,
            (int)player.Posizione.Y,
            player.Width,
            player.Height);
            //collisione per asteroide e navicella
            for (int i = 0; i < Asteroidi.Count; i++)
            {
                rectangleArea2 = new Rectangle((int)Asteroidi[i].Posizione.X,
                (int)Asteroidi[i].Posizione.Y,
                Asteroidi[i].Width,
                Asteroidi[i].Height);

                // Determina la collissione tra i due oggietti
                if (rectangleArea1.Intersects(rectangleArea2))
                {
                    //danni all'astronave
                    player.Carburante -= Asteroidi[i].DanniAstronave;

                    // energia
                    Asteroidi[i].Energia = 0;

                    //cambio lo stato attivo nel caso che ho finito il carburante
                    if (player.Carburante <= 0)
                        player.StatoAttivo = false;
                }

            }

            //Collisione tra il fuoco ed asteroide
            for (int i = 0; i < spari.Count; i++)
            {
                for (int j = 0; j < Asteroidi.Count; j++)
                {
                    //Creo e verifico e se le aree sono in collissioni
                    rectangleArea1 = new Rectangle((int)spari[i].Posizione.X -
                    spari[i].Width / 2, (int)spari[i].Posizione.Y -
                    spari[i].Height / 2, spari[i].Width, spari[i].Height);

                    rectangleArea2 = new Rectangle((int)Asteroidi[j].Posizione.X - Asteroidi[j].Width / 2,
                    (int)Asteroidi[j].Posizione.Y - Asteroidi[j].Height / 2,
                    Asteroidi[j].Width, Asteroidi[j].Height);

                    // Determina la collissione tra i due oggietti
                    if (rectangleArea1.Intersects(rectangleArea2))
                    {
                         
                        Asteroidi[j].Energia -= spari[i].Danno;
                        spari[i].StatoAttivo = false;
                    }
                }
            }

        }


        /// <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();

            spriteBatch.Draw(SfondoPrincipale, Vector2.Zero, Color.White);

            //visualizzo lo spostamento
            sfondo1.Draw(spriteBatch);
            sfondo2.Draw(spriteBatch);
            //aggiorno la visualizzazione della risorsa di tipo asteroide
            for (int i = 0; i < Asteroidi.Count; i++)
            {
                Asteroidi[i].Draw(spriteBatch);
            }
            //aggiorno la visualizzazione della risora di tipo fuoco
            for (int i = 0; i < spari.Count; i++)
            {
                spari[i].Draw(spriteBatch);
            }

            //aggiorno la visualizzazione
            player.Draw(spriteBatch);
            //termine del ridisegno
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

Il tutto sarà visualizzato come in figura 2


Figura 2

Conclusioni

La quinta parte ha illustrato la possibilità di gestire la collisione, e la gestione dell’armamento, in questa parte, si può comprendere come poter dotare il nostro gioco di ulteriori funzionalità.
Tramite la parola Download potete scaricare il file d’esempio.
Download

Nessun commento: