Como en todas las aplicaciones de C#, por defecto, el programa arranca en el método Main de la clase Program. Allí dentro, en los proyectos de MonoGame, se instancia un objeto del tipo Game y se llama a su método Run. Internamente, el primer método que se llama es Initialize. En este método hay que escribir todo el código relacionado a inicializar objetos relacionados con el juego. Inmediatamente se llama al método LoadContent una única vez, donde se carga todo lo relacionado al contenido del juego, como sprites, fuentes, audio, etc. Luego viene lo que se denomina "Game Loop" que es la repetición hasta el fin de la invocación a los métodos Update y Draw (aunque a veces no secuencialmente, pero si muchas veces por segundo) repetidamente de acuerdo al "Frame rate" que se haya especificado al inicializar. Update debe encargarse de tomar los inputs (teclado, gamepad, touchpad) del jugador y actualizar la física, la inteligencia artificial, el estado general del juego y las animaciones, aunque no de dibujarlas, solamente decidir el cuadro o frame que se debe mostrar. Draw es quien debe dibujar y actualizar la pantalla con lo que se debe ver. Finalmente UnloadContent es llamado cuando el juego se termina y es el encargado de liberar los recursos usados en el juego.
Como verán, es bastante simple. En Initialize lo común es iniciar el nivel, el jugador y todo lo relacionado con el juego. En LoadContent lo que se hace es cargar los recursos, por ejemplo:
protected override void LoadContent() { // Create a new SpriteBatch, which can be used to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); fuente = Content.Load<SpriteFont>("MiFuente"); heroe = Content.Load<Texture2D>("heroe"); }
En UnloadContent, iría la liberación, pero generalmente no hay recursos que necesiten ser liberados explícitamente. El grueso de nuestro juego va a estar en Update, donde vamos tomando el input del jugador y actualizando el estado del juego. Y por último en Draw va todo lo que dibujamos. Es muy importante que todas las llamadas a spriteBatch.Draw() se hagan entre los métodos spriteBatch.Begin() y spriteBatch.End(), pero no repitiendo estos últimos, sino que utilizándolos una única vez (o unas pocas en algunas excepciones) y llamando a spriteBatch.Draw() varias veces entre esos métodos. ¿Y por qué es esto? Habrán escuchado que las placas de video pueden dibujar millones de polígonos, pero si uno dibuja varias veces sin el cuidado anterior, la aplicación se ralentiza. El tema es que esos millones de polígonos deben venir todos juntos de una sola vez para optimizar el proceso y eso es lo que hace el Begin y End de spriteBatch, juntar todo lo que se dibuja y dibujar una sola vez.