Introducción a la Programación de
Videojuegos y Gráficos
GRADO EN INGENIERÍA
INFORMÁTICA
T3: VIDEOJUEGOS 2D Y 3D
3.1. Estructura de un videojuego.
3.2. Motores gráficos(perspectivas, estructuras de datos y
algoritmos de visualización, navegación).
3.3. Física (conceptos, colisiones, proyectiles, motores de físicas).
3.4. Programación gráfica 2D (APIs gráficas).
3.5.
Estructura de videojuegos 3D.
Modelos 3D (I)
• Los modelos 3D permiten dibujar figuras complejas sin necesidad de indicar todos y cada uno de los triángulos que la componen.
• Los modelos 3D se crean mediante herramientas externas a XNA, por ejemplo. • Blender • Maya • 3D Studio Max • Lightwave • Modo
• Estas herramientas exportan los modelos a múltiples formatos. XNA soporta los formatos .X y .FBX.
• Existen plugins para la mayoría de herramientas que permiten exportar los modelos creados a alguno de estos formatos.
Modelos 3D (II)
• Vamos a crear un proyecto nuevo que pinte un modelo 3D.
• Cread un nuevo proyecto XNA, que podéis llamar Game3D.
• Una vez creado el proyecto, añadidle la clase camara.cs que creasteis para el proyecto anterior (podéis descargar la clase de moodle).
• Modificad el namespace del fichero camara.cs a Game3D
• Añadid los siguientes espacios de nombres en el fichero camara.cs
using Microsoft.Xna.Framework.Net; using Microsoft.Xna.Framework.Storage;
• Modificad el plano lejano del campo de visión de la camara al valor 3000, es decir, en el constructor, cambiad
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width /(float)Game.Window.ClientBounds.Height,1, 100);
Por
projection = Matrix.CreatePerspectiveFieldOfView(MathHelper.PiOver4,
(float)Game.Window.ClientBounds.Width /(float)Game.Window.ClientBounds.Height,1, 3000);
• Añadid ahora la cámara a la clase Game1, para ello, añadid una variable de clase camara
public Camera camera { get; protected set; }
• y cread una instancia de la cámara en el método Initialize();
camera = new Camera(this, new Vector3(0, 0, 50), Vector3.Zero, Vector3.Up);
Modelos 3D (III)
• Cread una nueva clase de contenidos Models.
• Descargad de moodle el fichero spaceship.x y añadidlo al proyecto como contenido.
• Creamos una nueva clase que vamos a llamar BasicModel, a la que añadimos los siguientes espacios de nombres
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
• Las siguientes variables de clase
public Model model { get; protected set; } protected Matrix world = Matrix.Identity;
• El siguiente constructor
public BasicModel(Model m) { model = m; }
• Y el procedimiento Update()
Modelos 3D (IV)
• Un modelo 3D generado por una herramienta, puede contener varios objetos denominados mallas (meshes), la clase de XNA que respresenta cada una de estas mallas es ModelMesh.
• La clase Model contiene una lista de objetos ModelMesh.
• Cada malla (ModelMesh) puede contener multiples colores, texturas, etc. empleadas para dibujar la malla.
• La clase ModelMesh contiene a su vez una lista de ModelMeshParts dentro de la propiedad ModelParts.
• Cada ModelMeshPart contiene un effect así como los materiales que necesita para dibujarlo.
Modelos 3D (V)
• Añadid ahora la siguiente implementación del procedimiento Draw() para el objeto BasicModel.
public void Draw(Camera camera) {
Matrix[] transforms = new Matrix[model.Bones.Count]; model.CopyAbsoluteBoneTransformsTo(transforms); foreach (ModelMesh mesh in model.Meshes) {
foreach (BasicEffect be in mesh.Effects) { be.EnableDefaultLighting( ); be.Projection = camera.projection; be.View = camera.view;
be.World = GetWorld( ) * mesh.ParentBone.Transform; }
mesh.Draw( ); }
}
• Y añadid la siguiente función miembro.
Gestor de Modelos (I)
• Vamos a implementar un gestor de modelos, similar al gestor de sprites y al gestor de pantallas que ya hemos implementado anteriormente.
• Añadid una nueva clase ModelManager, usando el template GameComponent.
• Declaradlo de derivado de DrawableGameComponent.
• Añadid una lista de modelos como variable de clase y un nombre de contenido.
List<BasicModel> models = new List<BasicModel>( );
• Sobrepasad el procedimiento LoadContent
protected override void LoadContent( ) {
models.Add(new BasicModel(Game.Content.Load<Model>(@"models\spaceship"))); base.LoadContent( );
Gestor de Modelos (II)
• Sobrepasad ahora las funciones Draw y Update
public override void Draw(GameTime gameTime) { foreach (BasicModel bm in models)
{
bm.Draw(((Game1)Game).camera); }
base.Draw(gameTime); }
public override void Update(GameTime gameTime) { for (int i = 0; i < models.Count; ++i) {
models[i].Update( ); }
Base.Update(gameTime); }
• Declarad ahora una variable en la clase Game1 de tipo ModelManager
ModelManager modelManager;
• Dentro del procedimiento Initialize() Instanciad el Gestor de modelos y añadidlo a la lista de componentes.
modelManager = new ModelManager(this); Components.Add(modelManager);
Rotación de Modelos.
• Vamos a rotar el modelo. Para ello, añadid una nueva clase
SpinningEnemy derivada de BasicModel.
class SpinningEnemy:BasicModel { }
• Añadid los espacios de nombres
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Graphics;
• Añadid una variable de clase de tipo Matrix
Matrix rotation = Matrix.Identity;
• Añadid el constructor
public SpinningEnemy(Model m) : base(m) { }
• Y añadid las funciones Update() y GetWorld()
public override void Update( ) {
rotation *= Matrix.CreateRotationY(MathHelper.Pi / 180); }
public override Matrix GetWorld( ) { return world * rotation;
}
• Finalmente, en la clase ModelManager modificad la línea
models.Add(new BasicModel(Game.Content.Load<Model>(@"Models\spaceship")));
por
models.Add(new SpinningModel(Game.Content.Load<Model>(@"Models\spaceship")));