viernes, 12 de agosto de 2011

XNA – PingPong, Paletas


En el anterior tutorial vimos la introducción y el diseño de nuestro PingPong, en este tutorial crearemos la clase de las Paletas. Así que en nuestro proyecto que creamos en el anterior tutorial, crearemos la clase Paleta.cs. Variables
Texture2D textura;
Vector2 posicion;
Vector2 posicionIni;
Vector2 tamañoventana;
public BoundingBox bbox;
Textura y posicion: Variables básicas, en una guardamos la textura de la paleta y en otra su posición. posicionIni: Guardamos la posición al momento de iniciar el juego, la utilizamos para el Reset de nuestra paleta. tamañoventana: Lo usamos para chequear las colisiones de la ventana y la paleta. bbox: El bounding Box de nuestra paleta, la hacemos publica para poder acceder a ella luego.
Constructor Bien, nosotros en nuestro juego tenemos dos jugadores, si bien podríamos hacer dos clases una para el Player1 y otra para el Player2, no tendría demasiado sentido ya que el codigo entre los dos es exactamente el mismo, así que lo que haremos es distinguir en el constructor cual es el Player1 y el Player2, luego de esto almacenar los datos.
public Paleta(int Player, Inicio init)
{
if (Player == 1)
{
textura = init.Content.Load< Texture2D >("player1");
posicion = new Vector2(20, init.Window.ClientBounds.Height / 2);
posicionIni = posicion;
}
else
{
textura = init.Content.Load< Texture2D >("player2");
posicion = new Vector2(init.Window.ClientBounds.Width - textura.Width - 20, init.Window.ClientBounds.Height / 2);posicionIni = posicion;
}
 
tamañoventana = new Vector2(init.Window.ClientBounds.Width, init.Window.ClientBounds.Height);}
Los datos que pide al momento de iniciar la clase Paleta.cs, Player la usamos para saber que jugador vamos a configurar(1 o 2), e Inicio la usamos para tomar los datos del tamaño de la ventana y usar el Content para cargar las texturas. Si Player es igual a 1, entonces cargamos la textura del jugador 1 y la posición que le corresponde al jugador 1(y guarda su posición inicial), en caso de que el valor de Player sea 2, entonces hará lo mismo pero guardando datos correspondiente al Player2. Update
public void Update(){KeyboardState ks = Keyboard.GetState();
 
//Player 1
if (posicion.X == 20)
{
if (ks.IsKeyDown(Keys.Q))
{
if (posicion.Y > 0)
{
posicion.Y -= 7;
}
}
if (ks.IsKeyDown(Keys.A))
{
if (posicion.Y < tamañoventana.Y - textura.Height)
{
posicion.Y += 7;
}
}
}
// ______________________________
else
//Player2
{
if (ks.IsKeyDown(Keys.P))
{
if (posicion.Y > 0)
{
posicion.Y -= 7;
}
}
if (ks.IsKeyDown(Keys.L))
{
if (posicion.Y < tamañoventana.Y - textura.Height){posicion.Y += 7;
}
}
}
//________________________________
 
bbox = new BoundingBox(new Vector3(posicion, 0),new Vector3(posicion.X + textura.Width, posicion.Y + textura.Height, 0));}
Un poco desordenado, pero miren atentamente. Como nosotros distinguimos en el constructor cual es el Player1 y el Player2, debemos hacer lo mismo en el Update para asignarle los controles. Si miran, verán que dividimos el if en dos bloques con los comentarios, el primero le corresponde al Player1, y el segundo al Player2. Si nos ponemos en el bloque del Player1 tenemos dos IF, ambos son para los controles, pero si ven con mas cuidado verán que dentro de IF del Keys.Q hay otro IF. Ese IF lo usamos para decirle a la paleta que solo va a poder subir para arriba hasta que su posición de Y sea 0, dicho en otras palabras, hasta que toque el “techo” de la ventana. Ahora si nos fijamos en el Keys.A veremos que hay otra cosa comparando, por que pusimos “posicion.Y < tamañoventana.Y – textura.Height” en ves de “posicion.Y < tamañoventana.Y”?, la razón es la siguiente:
Las posiciones se toman desde la esquina superior izquierda de la textura, por esa razon si ponemos la opcion de la primera foto, la textura se va a pasar de la ventana, pero solo se pasa una cantidad igual al alto de la textura. Por eso para que no haga eso, a la posicion Y le restamos su altura, para que asi quede bien la colision. Los otros dos if del Player2 tienen la misma logica. Dibujado y Reset
public void Draw(SpriteBatch SB)
{
SB.Draw(textura, posicion, Color.White);
}
 
public void Reset()
{
posicion = posicionIni;
}
Iniciando las paletas Ahora vamos a la calse Inicio.cs, y crearemos la siguiente variables.
Paleta player1;Paleta player2;
Las iniciamos.
player1 = new Paleta(1, this);player2 = new Paleta(2, this);
En el Update.
player1.Update();player2.Update();
Y por ultimo en el Draw.
player1.Draw(spriteBatch);player2.Draw(spriteBatch);
Si iniciamos esto tendriamos algo como esto.
Aca termina el tutorial para hacer las paletas, en el proximo haremos la clase Bola.cs.
Paleta.cs
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;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
 
namespace MiJuego_Tutorial_9
{
public class Paleta{
Texture2D textura;
Vector2 posicion;
Vector2 posicionIni; //Se usa para el Reset
 
Vector2 tamañoventana; //Se usa para la colision de las ventanas
public BoundingBox bbox; //Se hace publico para pasarle el dato a la clase Bola.cs
 
public Paleta(int Player, Inicio init)
{
//Depende que valor le pasamos a Player(1 o 2) le almacena una textura y posicion diferente
if (Player == 1)
{
textura = init.Content.Load< Texture2D >("player1");
posicion = new Vector2(20, init.Window.ClientBounds.Height / 2);
posicionIni = posicion;}else{textura = init.Content.Load< Texture2D >("player2");
posicion = new Vector2(init.Window.ClientBounds.Width - textura.Width - 20, init.Window.ClientBounds.Height / 2);
posicionIni = posicion;
}
 
tamañoventana = new Vector2(init.Window.ClientBounds.Width, init.Window.ClientBounds.Height);
}
 
public void Update()
{
KeyboardState ks = Keyboard.GetState();
 
//Player 1
if (posicion.X == 20)
{
if (ks.IsKeyDown(Keys.Q))
{
if (posicion.Y > 0)
{
posicion.Y -= 7;
}
}
if (ks.IsKeyDown(Keys.A))
{
if (posicion.Y < tamañoventana.Y - textura.Height)
{
posicion.Y += 7;
}
}
}
// ______________________________
else
//Player2
{
if (ks.IsKeyDown(Keys.P))
{
if (posicion.Y > 0)
{
posicion.Y -= 7;
}
}
if (ks.IsKeyDown(Keys.L))
{
if (posicion.Y < tamañoventana.Y - textura.Height)
{posicion.Y += 7;
}
}
}
//________________________________
 
bbox = new BoundingBox(new Vector3(posicion, 0),new Vector3(posicion.X + textura.Width, posicion.Y + textura.Height, 0));}
 
public void Draw(SpriteBatch SB){SB.Draw(textura, posicion, Color.White);
}
 
public void Reset()
{
posicion = posicionIni;
}
}
}
Inicio.cs
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;
using Microsoft.Xna.Framework.Net;
using Microsoft.Xna.Framework.Storage;
 
namespace MiJuego_Tutorial_9
{
public class Inicio : Microsoft.Xna.Framework.Game
{
GraphicsDeviceManager graphics;
SpriteBatch spriteBatch;
 
Paleta player1;
Paleta player2;
Texture2D fondo;
 
public Inicio()
{
graphics = new GraphicsDeviceManager(this);
graphics.PreferredBackBufferWidth = 800;
graphics.PreferredBackBufferHeight = 600;
Content.RootDirectory = "Content";
}
 
protected override void Initialize(){
base.Initialize();
}
 
protected override void LoadContent()
{
spriteBatch = new SpriteBatch(GraphicsDevice);
player1 = new Paleta(1, this);
player2 = new Paleta(2, this);
fondo = Content.Load<>("fondo");
}
 
protected override void UnloadContent(){
 
}
 
protected override void Update(GameTime gameTime)
{
player1.Update();
player2.Update();
 
base.Update(gameTime);
}
 
protected override void Draw(GameTime gameTime)
{
GraphicsDevice.Clear(Color.CornflowerBlue);
 
spriteBatch.Begin();
spriteBatch.Draw(fondo, new Rectangle(0, 0, Window.ClientBounds.Width, Window.ClientBounds.Height), Color.White);
player1.Draw(spriteBatch);
player2.Draw(spriteBatch);
spriteBatch.End();
 
base.Draw(gameTime);
}
}
}