Inicio > Mis cosas, XNA > Tutorial [Entrega 5]: Añadiendo disparos de los enemigos

Tutorial [Entrega 5]: Añadiendo disparos de los enemigos

Llegados a este punto, tenemos nuestra nave frente a unas cuantas naves enemigas. Nuestra nave puede disparar y eliminar a los enemigos, pero los enemigos todavía no pueden dispara para intentar eliminarnos. Vamos a ver como podemos hacer esto después del salto.

 

Como ya sabéis, si tenéis alguna duda, podéis plantearla en el foro: http://www.foro.xna-tutorial.com/viewtopic.php?f=4&p=8#p8

 

Añadir los disparos de los enemigos, dado el código que tenemos ya escrito en anteriores entregas del tutorial, va a ser realmente fácil.

Veamos los cambios que debemos introducir según las clases.

 

Clase “Enemigo”

Lógicamente, esta será la clase que debemos modificar. Lo que haremos será principalmente generar un numero aleatorio, el cual nos indicará si el enemigo debe disparar o no debe disparar. Manos a la obra.

Primero nos definiremos dos nuevos atributos:

  1         static Random rand = new Random();
  2         public int probabilidadDisparo = 2;

 

El número 2 de “probabilidadDisparo”  es la cota que indica si debe disparar o no. Si subimos ese número, los enemigos dispararan más a menudo. De esta forma podemos aumentar el nivel de dificultad (la cadencia de disparos enemigos) simplemente incrementando ese valor.

 

Ahora vamos al método “Actualizar()”, y le añadimos lo siguiente:

  1         public void actualiza()
  2         {
  3
  4             if (disp == null)
  5             {
  6                 if (rand.Next(1000) < probabilidadDisparo)
  7                     disparar();
  8             }
  9             else
10             {
11                 disp.actualiza();
12             }
13            
14         }

 

Esto lo que hará será obtener un nuevo numero aleatorio, y si ese numero es menor que la cota de “probabilidadDisparo” entonces disparará. Esto solo lo hará si el enemigo no ha disparado (recordemos que cada nave solo puede tener un disparo al mismo tiempo). Si ya había disparado, entonces actualizaremos el disparo.

 

 

Clase “Nave”

En esta clase vamos a definir una propiedad que nos devuelva el rectángulo que envuelve a la nave para poder comprobar las colisiones. Es un cambio menor.

  1         public Rectangle Rectangulo
  2         {
  3             get { return new Rectangle((int)pos.X, (int)pos.Y, textura.Width, textura.Height); }
  4         }

 

 

 

Clase “Game”

Y ahora viene la chica: si unos de los disparos del enemigo nos da, tenemos que eliminar nuestra nave. En próximas versiones lo que haremos será decrementar el contador de vidas de nuestra nave, pero ahora sólo tendremos una vida.

Así que antes de comprobar la colisión de nuestros disparos con los enemigos, que lo vimos en la anterior entrega, comprobaremos que ningún disparo de los enemigos colisione con nuestra nave. Si colisiona, eliminaremos nuestra nave.

 

  1             foreach (Enemigo e in enemigos)
  2             {
  3                 if (e.Disparo != null && nave != null)
  4                 {
  5                     if (e.Disparo.Rect.Intersects(nave.Rectangulo))
  6                     {
  7                         nave = null;
  8                         e.Disparo = null;
  9                     }
10                 }
11             }

 

 

Como ahora nuestra nave puede ser null, tenemos que cambiar todas las referencias a nuestra nave para que antes de ejecutar cualquier cosa compruebe que la nave no es null. Si no lo hacemos, nuestro juego “petará” cuando nos de un impacto. El código entero de la clase “game” es el siguiente:

  1 using System;
  2 using System.Collections.Generic;
  3 using System.Collections;
  4 using System.Linq;
  5 using Microsoft.Xna.Framework;
  6 using Microsoft.Xna.Framework.Audio;
  7 using Microsoft.Xna.Framework.Content;
  8 using Microsoft.Xna.Framework.GamerServices;
  9 using Microsoft.Xna.Framework.Graphics;
10 using Microsoft.Xna.Framework.Input;
11 using Microsoft.Xna.Framework.Media;
12 using Microsoft.Xna.Framework.Net;
13 using Microsoft.Xna.Framework.Storage;
14
15 namespace spaceInvaders
16 {
17     /// <summary>
18     /// This is the main type for your game
19     /// </summary>
20     public class Game1 : Microsoft.Xna.Framework.Game
21     {
22         GraphicsDeviceManager graphics;
23         SpriteBatch spriteBatch;
24         Nave nave;
25         //Enemigo enemigo;
26         ArrayList enemigos;
27         
28
29         /// <summary>
30         /// Constructor de la clase
31         /// </summary>
32         public Game1()
33         {
34             graphics = new GraphicsDeviceManager(this);
35             Content.RootDirectory = "Content";
36             
37         }
38
39         /// <summary>
40         /// Allows the game to perform any initialization it needs to before starting to run.
41         /// This is where it can query for any required services and load any non-graphic
42         /// related content.  Calling base.Initialize will enumerate through any components
43         /// and initialize them as well.
44         /// </summary>
45         protected override void Initialize()
46         {
47             // TODO: Add your initialization logic here
48             nave = new Nave();
49             enemigos = new ArrayList();
50
51
52             base.Initialize();
53         }
54
55         /// <summary>
56         /// LoadContent will be called once per game and is the place to load
57         /// all of your content.
58         /// </summary>
59         protected override void LoadContent()
60         {
61             // Create a new SpriteBatch, which can be used to draw textures.
62             spriteBatch = new SpriteBatch(GraphicsDevice);
63             
64             //Le decimos a la nave que textura tiene que cargar
65             nave.Textura = Content.Load<Texture2D>("nave");
66             nave.TexturaDisparo = Content.Load<Texture2D>("disparoNave");
67
68
69             //Creamos los enemigos y los metemos en el arraylist
70             int numeroEnemigos = 5;
71             float X = 275;
72             float Y = 100;
73
74             for (int i = 0; i < numeroEnemigos;i++)
75             {
76                 Vector2 pos = new Vector2(X, Y);
77                 Enemigo e = new Enemigo(pos);
78                 enemigos.Add(e);
79                 X += 50;
80             }
81             
82             //cargamos las texturas del enemigo
83             foreach(Enemigo e in enemigos)
84             {
85                 e.Textura = Content.Load<Texture2D>("enemigo");
86                 e.TexturaDisparo = Content.Load<Texture2D>("disparoNave");
87             }
88             // TODO: use this.Content to load your game content here
89         }
90
91         /// <summary>
92         /// UnloadContent will be called once per game and is the place to unload
93         /// all content.
94         /// </summary>
95         protected override void UnloadContent()
96         {
97             // TODO: Unload any non ContentManager content here
98         }
99
100         /// <summary>
101         /// Allows the game to run logic such as updating the world,
102         /// checking for collisions, gathering input, and playing audio.
103         /// </summary>
104         /// <param name="gameTime">Provides a snapshot of timing values.</param>
105         protected override void Update(GameTime gameTime)
106         {
107             // Allows the game to exit
108             if (Keyboard.GetState().IsKeyDown(Keys.Escape))
109                 this.Exit();
110
111             // TODO: Add your update logic here
112             if (nave != null)
113                 nave.actualiza();
114
115
116             foreach (Enemigo e in enemigos)
117             {
118                 e.actualiza();
119             }
120
121
122             //comprobamos si algun disparo enemigo nos ha dado
123             foreach (Enemigo e in enemigos)
124             {
125                 if (e.Disparo != null && nave != null)
126                 {
127                     if (e.Disparo.Rect.Intersects(nave.Rectangulo))
128                     {
129                         nave = null;
130                         e.Disparo = null;
131                     }
132                 }
133             }
134
135             //Comprobamos que el disparo colisiona con algun enemigo
136             //Si colisiona, eliminamos el enemigo y el disparo
137             
138             //Array auxiliar para alamacenar los enemigos que debemos eliminar
139             ArrayList eliminar = new ArrayList();
140
141             //Si no hay disparo, no hace falta que entre
142             if (nave != null && nave.Disparo != null)
143             {
144                 //Recorremos la lista de enemigos y comprobamos si alguno colisiona
145                 foreach (Enemigo e in enemigos)
146                 {
147                     Rectangle rectEnemigo = e.Rect;
148                     Rectangle rectDisparo = nave.Disparo.Rect;
149
150                     if (rectEnemigo.Intersects(rectDisparo))
151                     {
152                         //añadimos al enemigo a la lista a eliminar
153                         eliminar.Add(e);
154                     }
155                 }
156
157                 //si la lista de enemigos a eliminar no esta vacia
158                 if (eliminar.Count > 0)
159                 {
160                     foreach (Enemigo el in eliminar)
161                     {
162                         //eliminamos al enemigo
163                         enemigos.Remove(el);
164                     }
165
166                     //eliminamos el disparo
167                     nave.Disparo = null;
168                 }
169             }
170
171
172             base.Update(gameTime);
173         }
174
175         /// <summary>
176         /// This is called when the game should draw itself.
177         /// </summary>
178         /// <param name="gameTime">Provides a snapshot of timing values.</param>
179         protected override void Draw(GameTime gameTime)
180         {
181             GraphicsDevice.Clear(Color.Black);
182
183             // TODO: Add your drawing code here
184             spriteBatch.Begin();
185             
186            if (nave != null) nave.Draw(spriteBatch); //pitnamos la nave
187             foreach (Enemigo e in enemigos)
188             {
189                 e.Draw(spriteBatch);
190             }
191             
192
193             spriteBatch.End();
194
195
196             base.Draw(gameTime);
197         }
198     }
199 }
200

 

 

Y ya está! ya tenemos nuestros enemigos disparando y nosotros también disparando.

Como siempre, puedes bajarte el código fuente del siguiente enlace:

down  Descargar Código Fuente del tutorial

 

 

Un saludo y hasta la próxima entrega!

Categorías:Mis cosas, XNA Etiquetas: , ,
  1. Aún no hay comentarios.
  1. No trackbacks yet.

Responder

Introduce tus datos o haz clic en un icono para iniciar sesión:

Logo de WordPress.com

Estás comentando usando tu cuenta de WordPress.com. Cerrar sesión / Cambiar )

Imagen de Twitter

Estás comentando usando tu cuenta de Twitter. Cerrar sesión / Cambiar )

Foto de Facebook

Estás comentando usando tu cuenta de Facebook. Cerrar sesión / Cambiar )

Google+ photo

Estás comentando usando tu cuenta de Google+. Cerrar sesión / Cambiar )

Conectando a %s

A %d blogueros les gusta esto: