Volver al Inicio Microsoft Student Tech Club: Universidad Libre

Tutorial de XNA: Controlando al protagonista de nuestro juego
 

El control de un juego se logra con el mouse, con el teclado o con el gamepad. Si jugamos con XBOX tenemos gamepad pero no tenemos teclado.

Gamepad

El código a escribir para leer lo que hace el usuario con algún control es en Update( ), como se ve en la imagen

El código original de este método es el siguiente:

/// <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

base.Update(gameTime);

}

Procedemos entonces a modificar ese método agregando nuestro código tanto para controles XBOX como el teclado y mouse en PC. En una gamepad hay un control llamado thumbstick con el que se controlará el ángulo del lanzador.

Hay que agregar una directiva de compilación en Visual C#, para que en caso que la aplicación ejecute en una XBOX no intente leer teclado ni mouse.

Las instrucciones #if ... #endif   se conocen como Preprocessor Directives y son necesarias si requiere generar el código dependiendo de parámetros del compilador. En este caso si el ejecutable va para una XBOX o para un PC.

Debemos adicionar la declaración de anteriorRaton al inicio de la clase como se ve en la imagen.

El código completo de Game1.cs se muestra a continuación:

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 PrimerJuego
{
    /// <summary>
    /// This is the main type for your game
    /// </summary>
    public class Game1 : Microsoft.Xna.Framework.Game
    {
        GraphicsDeviceManager graphics;
        SpriteBatch spriteBatch; //Contenedor de los sprite
        Texture2D Fondo; //Variable de tipo textura que tendrá el fondo
        Rectangle rectFondo; //Un rectángulo donde estará la textura del fondo
        ObjetosJuego lanzador; //El lanzador
        ObjetosJuego baselanzador; //Base del lanzador
        //Almacena el estado anterior del ratón
        MouseState anteriorRaton;
        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
            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);
            // TODO: use this.Content to load your game content here
            //Utiliza genéricos <> por eso el uso de <> En C++ se llaman plantillas. Content carga el contenido binario.
            Fondo = Content.Load<Texture2D>("Imagenes\\FondoJuego");
            //El rectángulo en el que estará contenido el fondo
            rectFondo = new Rectangle(0, 0, graphics.GraphicsDevice.Viewport.Width, graphics.GraphicsDevice.Viewport.Height);
            //Cargar e inicializar el Lanzador
            lanzador = new ObjetosJuego(Content.Load<Texture2D>("Imagenes\\Lanzador")); //No es necesaria la extension .tga
            lanzador.posicion = new Vector2(160, 530); //Posicion del lanzador
            //Cargar e inicializar la base
            baselanzador = new ObjetosJuego(Content.Load<Texture2D>("Imagenes\\Base")); //No es necesaria la extension .tga
            baselanzador.posicion = new Vector2(70, 560); //Posicion de la base del lanzador
        }
        /// <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();
            // Código para leer el estado del Gamepad de una XBOX. Se considera que hay un jugador al menos.
            GamePadState estadoControl = GamePad.GetState(PlayerIndex.One);
            //Como hay que tener en cuenta los controles del XBOX llamados thumbstick, se
            //observa que botón del XBOX oprimió, eso genera una constante algo grande por lo que se multiplica por 0.1
            lanzador.rotacion += estadoControl.ThumbSticks.Left.X * 0.1f;
//Esta es una compilación condicional. El teclado y el mouse solo son leídos si la aplicación ejecuta en un PC
#if !XBOX
            //Código para leer el teclado
            KeyboardState estadoTeclado = Keyboard.GetState();
            if (estadoTeclado.IsKeyDown(Keys.Left)) lanzador.rotacion -= 0.1f;  //Gira el lanzador hacia la izquierda
            if (estadoTeclado.IsKeyDown(Keys.Right)) lanzador.rotacion += 0.1f; //Gira el lanzador hacia la derecha
            //Código para leer el ratón
            MouseState Raton = Mouse.GetState();
            //Si movió el ratón entonces el lanzador cambia de ángulo 
            if (Raton != anteriorRaton)
            {
                int DiferX = Raton.X - anteriorRaton.X; //La diferencia entre la anterior posición del ratón y la nueva.
                lanzador.rotacion += (float)DiferX / 100; //El movimiento en X del ratón cambia el ángulo del lanzador
            }
            //Se actualiza el estado del ratón
            anteriorRaton = Raton;
#endif
            //Esta instrucción limita entre 0 y 90 grados el giro del lanzador. Recordar que se hace uso de radianes.
            lanzador.rotacion = MathHelper.Clamp(lanzador.rotacion, -MathHelper.PiOver2, 0);
            base.Update(gameTime);
        }
        /// <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.CornflowerBlue);
            // TODO: Add your drawing code here
            //Se inicia el spritebatch (Entre Begin y End se dibuja en cada unidad de tiempo los sprites)
            spriteBatch.Begin(SpriteBlendMode.AlphaBlend);
            //Dibujar el fondo combinando el color blanco con el fondo
            spriteBatch.Draw(Fondo, rectFondo, Color.White);
            //Dibuja la base del lanzador combinando con blanco
            spriteBatch.Draw(baselanzador.sprite, baselanzador.posicion, Color.White);
            /* Dibuja el lanzador como tal, estos son los parámetros
             * Parámetro 1: El sprite del lanzador
             * Parámetro 2: La posición del lanzador
             * Parámetro 3: null porque es solo una imagen (no una sucesión de estas
             * Parámetro 4: Color.White, combinación de color
             * Parámetro 5: Angulo de rotación por defecto
             * Parámetro 6: Centro, el centro del sprite para girarlo después
             * Parámetro 7: Escala a dibujar 
             * Parametro 8: Dibujar tal como es el sprite (no reflejo vertical ni horizontal)
             * Parámetro 9: Ponerlo en la capa superior */
            spriteBatch.Draw(lanzador.sprite, lanzador.posicion, null, Color.White, lanzador.rotacion, lanzador.centro, 0.6f, SpriteEffects.None, 0);
            //Finaliza el "ciclo" de los sprite
            spriteBatch.End();
            base.Draw(gameTime);
        }
    }
}

Este es el resultado al ejecutar el programa

 

 

Volver al Inicio Célula Microsoft. Universidad Libre