sábado, 22 de septiembre de 2012

Escribir con XNA

En la publicación anterior, que denominé Hola Mundo, no hice referencia a como escribir el clásico cartel de "Hola Mundo" por pantalla. Cualquiera pensaría que es tan simple como hacer un print o similar, pero no es así. La verdad es que conlleva varios pasos. Tantos que tuve que buscar en Internet como hacerlo.


¿Pero tan difícil es? Bueno, no tanto, pero hay que hacer algunas cosas raras que no se hacen en otros programas para hacer un simple "Hola mundo". El tema es que para escribir con XNA, hay que "dibujar" un string con un método que pide especificar la fuente con un objeto SpriteFont. Y esta clase no trae miembros estáticos con valores comunes como la clase Color o Pens. Tampoco se puede hacer facilmente un new SpriteFont(). Para crear una fuente, se debe agregar un elemento nuevo al proyecto Content (el que está vacío y que se usar para los recursos del juego) con la plantilla Sprite Font. Ponemos el nombre que queramos y aparece un archivo xml donde se especifica las propiedades de la fuente. La más importante es "FontName" que dice qué fuente se va a importar. Esto quiere decir que se toma de las fuentes del sistema operativo, así que tenerlo muy presente cuando quieran usar fuentes instaladas a parte. La que viene (Segoe UI Mono) parece buena, pero siéntanse libres de cambiarla para ver como queda.

 <?xml version="1.0" encoding="utf-8"?>  
 <XnaContent xmlns:Graphics="Microsoft.Xna.Framework.Content.Pipeline.Graphics">  
  <Asset Type="Graphics:FontDescription">  
   <FontName>Segoe UI Mono</FontName>  
   <Size>14</Size>  
   <Spacing>0</Spacing>  
   <UseKerning>true</UseKerning>  
   <Style>Regular</Style>  
   <CharacterRegions>  
    <CharacterRegion>  
     <Start>&#32;</Start>  
     <End>&#126;</End>  
    </CharacterRegion>  
   </CharacterRegions>  
  </Asset>  
 </XnaContent>  

Una vez creado el elemento fuente en el proyecto de contenido, sólo resta crear una variable del tipo SpriteFont en nuestra clase principal (Game1 si no le cambiaste el nombre) y luego cargar la fuente en el método LoadContent:

 GraphicsDeviceManager graphics;  
 SpriteBatch spriteBatch;  
 SpriteFont fuente;

 protected override void LoadContent()  
 {  
     // Create a new SpriteBatch, which can be used to draw textures.  
     spriteBatch = new SpriteBatch(GraphicsDevice);  
     fuente = Content.Load<SpriteFont>("MiFuente");
 }  

Fíjense que no es necesario pedir memoria (asignar new) a "fuente" porque el objeto lo devuelve el método Load de Content, tal como sucederá con otros recursos como las imágenes.

Ahora si, vamos a escribir el famoso cartel. Para hacerlo, usaremos el método DrawString de nuestro SpriteBatch. Este método pide un objeto SpriteFont, el string a dibujar, la ubicación y el color. El primero es nuestro objeto "fuente" o como le hayan puesto ustedes. El string es "Hola Mundo". La ubicación es un objeto del tipo Vector2 que son muy similares a los Point, tienen un componente X y un componente Y. Podríamos hacerlo sencillo y poner new Vector2(20, 20), pero vamos a hacer algo más interesante y calcular el punto medio de la pantalla.

La parte que se dibuja en la ventana es representada con un objeto del tipo ViewPort. En nuestro juego se puede acceder mediante GraphicsDevice.Viewport. De aquí mismo podemos recuperar la altura y el ancho de la pantalla, pero vamos a acceder a TitleSafeArea que devuelve la zona segura para escribir. Y ahí si accedemos a Height y Width. Con esos valores armamos un objeto Vector2 y luego lo dividimos por 2 (Vector2.Divide). También se puede armar el vector con cada valor divido en 2.

¿Ya está? Casi. Si dibujamos en ese punto, el texto empezará en dicho punto, por lo que NO estará centrado en la pantalla. ¿Como escribir centrado en ese punto? Para ello tendremos que restarle al punto, la mitad del tamaño de la frase "Hola Mundo".


Para saber cuanto mide un string, se usa el método MeasureString que viene con el objeto SpriteFont. Eso devuelve un punto. Ese punto lo dividimos a la mitad y se lo restamos al punto medio calculado anteriormente. Y ahora si estamos en condiciones de dibujar el cartel en el medio de la pantalla. El color lo dejamos a gusto de cada uno.

         protected override void Draw(GameTime gameTime)  
         {  
             GraphicsDevice.Clear(Color.Black);  
             spriteBatch.Begin();  
             //  
             Vector2 pos = new Vector2(GraphicsDevice.Viewport.TitleSafeArea.Width, GraphicsDevice.Viewport.TitleSafeArea.Height);  
             pos = Vector2.Divide(pos,2);  
             Vector2 tamaño = fuente.MeasureString("Hola Mundo");  
             pos -= Vector2.Divide(tamaño, 2);  
             spriteBatch.DrawString(fuente, "Hola Mundo", pos, Color.ForestGreen);  
             //  
             spriteBatch.End();  
             base.Draw(gameTime);  
         }  

Bien, eso fue todo. Esperando que el artículo lo hayan disfrutado tanto como yo al escribirlo, sólo resta dejar el link al código fuente y un saludo. Hasta la próxima entrega.

Descargar código fuente

sábado, 25 de febrero de 2012

Hola Mundo!




Y si, lo primero que hay que hacer con algo nuevo, el hola mundo.
Bueno en este blog voy a ir poniendo principalmente, mis experiencias con el desarrollo de juegos. También habrá otras noticias relacionadas con la informática en general.


Encontré un muy buen tutorial para hacer juegos con xna: Shooter
Es sencillo y trae todos los sprites y sonidos necesarios. Si bien el juego es simplón, sienta bases para mejores desarrollos y también por si quieres convertirlo en algo mejorado. El tutorial toma algo así como 90 minutos, incluyendo los videos. Está en inglés, espero que no desmotive.


Bien, esto fue todo por ahora. En las próximas entradas, más sobre xna y ese tutorial -¿traducción al español?- que la verdad estuvo muy entretenido. De hecho ya estoy trabajando en una remake del bomberman!!!