2. Agenda
Comenzar la creación de un juego tipo Arcade.
Aprender las técnicas de diseño de software que se
aplican al desarrollo de los juegos.
Aprender más acerca de los programas en su
construcción y ejecución.
Observar cómo organizar apropiadamente el
contenido de un juego y el programa en cinismo.
Realizar una refactorización simple
3. La idea del juego
El punto de inicio del
juego es el contenido de
una bolsa de compras.
Este contiene algunas
comidas que se deben
comprar.
Vamos a utilizar estos
objetos como la base del
juego, donde el pan
golpear el queso
alrededor de la pantalla
4. Crear las gráficas del juego
Es necesario conocer una
persona que trabaje con las
imágenes.
Esto probablemente
involucre a un diseñador
gráfico.
Un editor de gráficas es
necesario de igual manera,
que permita trabajar con
transparencias.
Esto hará posible crear un
entorno natural para los
objetos
5. Editor de gráficos
Una posible solución
puede ser utilizar
photoshop.
Una buena solución en
libere es Paint.net
www.getpaint.net
Esta herramienta nos
permite manipular
imágenes en capas y
soporta las transparencias
6. Formato de las imágenes
XNA permite utilizar imágenes en diversos formatos.
Los formatos jpg y gif pueden ser utilizados, pero estos
no soportan transparencias.
El formato standard deberá ser PNG
Además habrá que asegurarse que las imágenes no sea
muy grandes.
No se necesita más que unos cuantos cientos de píxeles
para las imágenes.
Es posible utilizar paint.net para ajustar las imágenes
7. Proyectos, recursos, clases
Para comenzar a hacer un juego lo primero que
debemos hacer es crear un proyecto.
Esto sirve como un contenedor para todos los recursos
del juego
Antes de construir el juego, es bueno dar un vistazo a
todos los elementos del proyecto y ver cuál es la mejor
manera de organizarlos.
Este conocimiento para que nuestros programas sean
más fáciles de ver
8. La solución
Se ha creado una solución
llamada BreadAndCheese
Este contiene todos los
archivos de programa y el
contenido del juego
El visual studio organiza
el contenido dentro de un
conjunto de folder.
Además podemos
adicionado nuestros
propios folder
9. Adicionar un folder
Uno puede ser es un lugar
de almacenamiento de
archivos en la computadora
donde se pueden colocar
cosas que serán
almacenadas en este lugar.
Todas las pistas de un
álbum en particular son
almacenadas en un solo
folder con la música.
Es aconsejable crearlos
nuestros propios folders
para organizar el contenido
10. Crear el folder para las imágenes
Una buena práctica es
mantener los sonidos y las
imágenes separados.
Esto hace más fácil de
usar el archivo, con tomar
el contenido de el folder.
En la imagen se mostró la
creación de un fuentes en
dentro del contenido
11. Adicionar al contenido
En se puede adicional
contenido a un folder en la
manera tradicional que se ha
venido haciendo.
En el proyecto, el folder de las
imágenes la ahora contiene las
imágenes para el pan y el queso
12. Cargando el contenido de este los
folders
Cuando una textura es cargada, es necesario adicionar
el nombre del folder junto con el nombre del asset.
El carácter / es utilizado para separar los nombres de
los folders en la ruta hacia el asset.
Si se colocarán una ruta de acceso errónea, el programa
va a compilar, pero fallara cuando se ejecute
breadTexture = Content.Load<Texture2D>("Images/Bread");
cheeseTexture = Content.Load<Texture2D>("Images/Cheese");
13. Los archivos del juego
Estamos bastante familiarizados con el archivo
Game1.cs
Este es el archivo que contiene los métodos para
actualizar y dibujar dentro del programa de juego.
Sin embargo esto no es el único programa dentro del
juego.
Tenemos además el archivo Program.cs
La éste es actualmente el archivo que hace que el juego
se ejecute
Echaremos un vistazo a este programa
14. El programa Program.cs
El programa Program.cs estén actualmente ejecuta el
juego
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
15. La sentencia using
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
16. Identifica un espacio de nombres
con using
La palabra using es utilizada para identificar un
espacio de nombres que será utilizado.
Esto le dice al compilador que utilice el nombre de
espacios llamado System
Un hombre despacio es algo donde el compilador mirá
para encontrar descripciones de recursos
Una lista importante de clases, incluyendo DateTime
son descritas dentro de este espacio de nombres
using System;
17. Crear nuestro propio espacio de
nombres
Esta sentencia crear un nombre de espacios para
nuestro juego
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
18. Creando un espacio de nombres
Los diseñadores de C# creado un nombre de espacios
llamado System donde colocaron las utilidades del
sistema.
Esta sentencia crear un nombre de espacios con el
nombre de BreadAndCheese.
Otros programas pueden localizar ítem en el espacio
de nombre BreadAndCheese utilizando using
namespace BreadAndCheese
19. Nombres bien calificados en los
espacios de nombre
Es posible utilizar objetos de un espacio de nombres
sin haber utilizado la sentencia que se coloca al inicio
del archivo.
Para hacer esto, se coloca el espacio de nombres antes
del nombre.
Un hombre bien calificado puede utilizarse si existe un
nombre de choque entre dos espacios de nombres.
Si se utilizan dos espacios el nombre que ambos
almacenado omiten con un hombre particular
System.DateTime currentTime = System.DateTime.Now;
20. Creando una clase
Este código crear una clase estática llamada program
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
21. La clase
Una clase es una colección de variables y métodos.
La clase programa, es la clase que actualmente
comienza la ejecución del programa.
Es estática porque solamente o contiene miembros
estáticos.
Dentro del compilador esto significa: siempre
presentes
static class Program
{
// Program class members go here...
}
22. Declarando del método main
Este código crea un espacio de nombres para nuestro
programa
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
23. El método main
Esta sentencia declara el método main para este
proyecto.
Es estática (lo cual significa siempre alli)
No retorna nada
Tiene como parámetros un arreglo de strings
Main es el método que se llama para iniciar la
ejecución de un programa
static void Main(string[] args)
{
// Main method statements go here
}
24. Crear una instancia de Game1
Este es otro uso de la palabra reservada using
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
25. La otra cara de using
Esta forma de using es una manera de ayudar al
colector de basura y decirle cuando un objeto puede
ser eliminado.
La construcción using crea un objeto Ita el único
bloque de sentencias en el cual es utilizado.
Cuando externo que finaliza el objeto puede ser
eliminado de la memoria
using (Game1 game = new Game1())
{
// Code that uses the game1 instance
}
// When we get here game1 can be destroyed
26. Ejecutando el juego
Esta sentencia y llama al método Run dentro del juego
using System;
namespace BreadAndCheese
{
static class Program
{
static void Main(string[] args)
{
using (Game1 game = new Game1())
{
game.Run();
}
}
}
}
27. Llamada del método Run en el
juego
Este método inicia todo lo de un juego XNA
Llama al método inicializar
Llamar al cargador de contenido
Inicia el proceso se llama al método actualizar y al
método dibujar se sentó a veces en un segundo.
Cuando el método Run finaliza el juego termina
game.Run();
28. La clase program
Actualmente no es necesario cambiar el contenido de
la clase program
Esta clase se cree automáticamente cuando visual
studio crear un nuevo proyecto
Sin embargo es utilizar saber cómo trabajan juntos y
que realmente pasa cuando un programa se ejecuta
Si se realiza una línea de comandos del archivo
program.cs , es posible colocar código directamente
dentro del método main
29. Renombrando la clase Game1
Una cosa que debemos hacer sin embargo es cambiar
el nombre de nuestra clase del juego del Game1
Esto tiene sentido para hacer que el nombre sea un
poco más significativo.
La clase del juego que debemos hacer realmente debe
de llamarse BreadAndCheese.
Visual studio hace esto de una manera muy fácil
30. Usar el renombrado en VS
Se puede renombrar un
ítem haciendo clic derecho
sobre este y visitar el nombre
requerido.
La renombrar las cosas para
que sus nombres sean más
significativos se conoce
como el nombre de
refactorizar y es una muy
buena manera de hacerlo los
programas más entendibles
31. Digitar el nuevo nombre
Veremos de asegurarnos
de no cambiar la
extensión .cs
Luego que cambiamos el
nombre, se actualizan
todas las referencias
dentro del proyecto
32. Renombrar las clases
Si sw renombra un programa, dice el estudio ofrecerá
renombrar las clases en el archivo.
Esto es muy útil, y deberíamos a responder
afirmativamente para que la clase Game1 sea
renombrada con el de BreadAndCheese
33. Resumen
Una buena solución es también una bien organizada.
El compilador provee espacios en hombres que permiten a
los programadores administrar los nombres de los ítems
Un juego se inicia por un código de la clase program la cual
llama al método de estático Main
Dentro del compilador estático significa: siempre presente
La instrucción using así que el colector de basura conozca a
quien debe eliminar
Los nombres de los intentos siempre deben reflejar lo que
ellos son
34. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible esperar el archivo program.cs de forma
manual
35. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible esperar el archivo program.cs de forma
manual
36. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible esperar el archivo program.cs de forma
manual
37. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible esperar el archivo program.cs de forma
manual
38. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible esperar el archivo program.cs de forma
manual
39. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible esperar el archivo program.cs de forma
manual
40. Verdadero y falso
Los proyectos que visual studio pueden contener
folders.
Estático significa que una variable no puede ser
cambiada.
Un espacio de nombres debe de iniciar con la letra n
Un programa inicia llamando al método Run
La sentencia using es utilizada para hacer los
programas pequeños
Es posible crear el archivo program.cs de forma
manual
42. Agenda
Tenemos un juego que contiene dos texturas que van a
ser utilizadas como los primeros internos del juego.
Estas deben ser de mencionadas para ajustarse a la
pantalla y luego animarlas, con un adecuado
movimiento.
Debemos de hacer esto teniendo en mente el hecho de
que los programas de juegos pueden ejecutarse en
diferentes plataformas, y con diferentes dimensiones
de pantalla
43. Crear un Sprite
Un sprite es un término para un objeto gráfico dentro
de un juego.
Un murciélago.
Un barco.
Un carácter.
Un sprite tiene contenido gráfico y una posición
particular en la pantalla.
En términos de XNA, con sprite será dibujado
basándose en un tipo de datos particular Texture2D
(para la imagen) y un rectánngle (para la posición)
44. El mundo del juego
La idea es que el queso será una pelota en nuestro
juego, y que el pan sea un bate.
Vamos a comenzar con tener el queso dentro de las
fronteras de la pantalla.
Este es el mundo del juego que será utilizado por el
método Draw cuando se tribuna de este sobre la
pantalla.
El método Update manejará estos valores
// Game World
Texture2D cheeseTexture;
Rectangle cheeseRectangle;
45. Administrar el tamaño
Un juego puede ejecutarse en diferentes plataformas
con diferentes tamaños de pantalla.
Es importante que se ajuste automáticamente los
tamaños de los objetos dentro de la pantalla que está
disponible.
Previamente vimos que un programa puede obtener el
alto y ancho de la pantalla.
El juego puede automáticamente calcular los tamaños
basándose en el tipo de pantalla.
46. La mostrar el tamaño
Se adicionan dos variables del mundo que nos darán el
ancho y alto de pantalla.
Estos han sido creados del tipo float para que sus
cálculos produzcan resultados del mismo tipo
// Display settings
float displayWidth;
float displayHeight;
protected override void Initialize()
{
displayWidth = GraphicsDevice.Viewport.Width;
displayHeight = GraphicsDevice.Viewport.Height;
base.Initialize();
}
47. Los tipos flotante y doble
Hay dos tipos de datos que pueden almacenar número
dos de punto flotante, float y double.
Float almacenar valores como una precisión de siete
dígitos
Double almacena valores con una precisión de
dieciséis dígitos.
Como los juegos se calculan valores muchas veces por
segundo a, algunas veces es necesario utilizar variables
de precisión doble para detener errores
Para nuestro juego los valores del tipo flotante son
adecuados
48. Valores punto flotante
Un Valor literaral es un Valor fijo que es colocado en
un programa (en esta sentencia el literaral es 3.14159)
Si el compilador de un Valor literaral con un punto
decimal en él, el compilador tratará el Valor al inicio
como del tipo double
Esto significa que la sentencia mostrada no compila
porque los valores del tipo doble son almacenados con
mayor precisión que los flotantes, y el compilador es
consciente acerca de la pérdida de datos durante la
asignación
float pi = 3.14159;
49. Crear un literal el tipo flotante
Se colocan la f después del literal, como se muestran,
el compilador reconocerá el Valor, de tipo flotante.
Este asignación compilada de manera correcta.
Además es posible utilizar un castin para corregir el
problema
La otra sentencia le indica el compilador que guarde la
precisión doble como flotante.
Recordemos que pasaremos el tipo flotante nuestro
juego
float pi = 3.14159f;
float pi = (float) 3.14159;
50. Relación de aspecto
La relación del aspecto de una imagen es la relación
entre el largo y el ancho.
Si esto es incorrecto la imagen no se verá bien.
El proceso de escalado debe preservar esta relación de
aspecto de los sprite
51. Calcular la relación
Un objeto Texture2D provee las propiedades width y
height que pueden ser utilizadas para calcular la
relación de aspecto de la imagen.
Para el sprite del pan, su aspecto Ronda 4
El pan es cuatro veces más ancho que alto
Cualquier tamaño de escala para el pan, prevé que
asegurar que se preserva esta relación
float aspectRatio =
(float) breadTexture.Width / breadTexture.Height;
52. Qué tan grande debe ser el queso
Cuando creamos un juego, es necesario decidir el
tamaño de los objetos.
Esto probablemente es algo cambie cuando se pruebe
del juego.
Es de alguna manera que sea fácil de cambiar el
tamaño de los objetos dentro del juego.
La variable de escala de darnos un hombre sensible y
ser parte del mundo del juego
53. La variable cheeseWidtFactor
Esta variable es configurada al valor de la 0.05
La esto significa que 20 quesos caben en lo ancho de la
pantalla
Podemos cambiar el Valor para diferentes tamaños sí
lo deseamos.
float cheeseWidthFactor = 0.05f;
54. Creando el método scaleSprite
Vamos a utilizar este método para escalar el sprite
El método será llamado desde el LoadContent
Vamos adicionar el escalamiento para el pan luego
void scaleSprites()
{
cheeseRectangle.Width =
(int)((displayWidth * cheeseWidthFactor) + 0.5f);
float aspectRatio =
(float) cheeseTexture.Width / cheeseTexture.Height;
cheeseRectangle.Height =
(int)((cheeseRectangle.Width / aspectRatio) + 0.5f);
}
55. Calcular el ancho del sprite
Mltiplicar la variable cheeseWidht por el ancho de la
pantalla para obtener el ancho del sprite del queso
El una pantalla de ancho de 800 píxeles, el queso
debería de tener un ancho de 40 píxeles
void scaleSprites()
{
cheeseRectangle.Width =
(int)((displayWidth * cheeseWidthFactor) + 0.5f);
float aspectRatio =
(float) cheeseTexture.Width / cheeseTexture.Height;
cheeseRectangle.Height =
(int)((cheeseRectangle.Width / aspectRatio) + 0.5f);
}
56. Calcular la relación de aspecto
Calcular la relación del aspecto de la textura del queso
que nos ha sido dada.
De utilizaremos esta misma para calcular el ancho
void scaleSprites()
{
cheeseRectangle.Width =
(int)((displayWidth * cheeseWidthFactor) + 0.5f);
float aspectRatio =
(float) cheeseTexture.Width / cheeseTexture.Height;
cheeseRectangle.Height =
(int)((cheeseRectangle.Width / aspectRatio) + 0.5f);
}
57. Calcular el altura
Calcular el ancho dividiendo el actual ancho por la
relación de aspecto de la textura originales.
No te que se convierte a un Valor del tipo entero
void scaleSprites()
{
cheeseRectangle.Width =
(int)((displayWidth * cheeseWidthFactor) + 0.5f);
float aspectRatio =
(float) cheeseTexture.Width / cheeseTexture.Height;
cheeseRectangle.Height =
(int)((cheeseRectangle.Width / aspectRatio) + 0.5f);
}
59. Crear el movimiento del queso
Ahora vamos a hacer que el queso se mueva.
Cada vez que el método Update es llamado, vamos a
cambiar el Valor de equis y de llega para el sprite del
queso
Para hacer esto necesitamos las variables que
almacenen esos valores
Estas serán parte del mundo del juego
float cheeseX;
float cheeseXSpeed;
float cheeseY;
float cheeseYSpeed;
60. Configurar los valores iniciales de
la velocidad
Es importante calcular la velocidad de los ítems de
acuerdo al tamaño de la pantalla que es utilizada.
De otra manera el juego casi será imposible jugar en
pantallas con un tamaño particular
Para hacer esto necesitamos configurar valores para
seleccionar la velocidad que se le quiera dar.
Vamos a configurar el número de veces que se
necesitan para conocer la pantalla
Por ejemplo si configuramos a 60, la textura cosas a la
pantalla en un segundo
61. Establecer la velocidad
Este Valor para aquellos que el queso se tarde 200 veces
en cruzar la pantalla, es decir alrededor de unos tres
segundos.
Podemos calcular el número de pasos requeridos.
Esto hará que el queso se mueva en una diagonal
float cheeseTicksToCrossScreen = 200.0f;
cheeseXSpeed = displayWidth / cheeseTicksToCrossScreen;
cheeseYSpeed = cheeseXSpeed;
62. Actualizar la posición
Estas son las sentencias para el movimiento del queso.
Actualizar los valores de la X, Y que sean utilizadas
para establecer los valores de cheeseRectangle
protected override void Update(GameTime gameTime)
{
// Test for exit here
cheeseX = cheeseX + cheeseXSpeed;
cheeseY = cheeseY + cheeseYSpeed;
cheeseRectangle.X = (int)(cheeseX + 0.5f);
cheeseRectangle.Y = (int)(cheeseY + 0.5f);
base.Update(gameTime);
}
64. Adicionar rebote
El juego no sería interesante si es que son desaparece
de la pantalla.
El programa debe de cambiar la dirección del
movimiento cuando golpee uno de los límites de la
pantalla.
Adición amos algunos pruebas para cambiar la
dirección de la velocidad cuando se alcanza una
frontera.
Se deberá hacer esto tanto para la X como para Y
65. Rebote en X
Esto nos hace crear un rebote en X
if (cheeseX + cheeseRectangle.Width >= displayWidth)
{
cheeseXSpeed = cheeseXSpeed * -1;
}
if (cheeseX <= 0)
{
cheeseXSpeed = cheeseXSpeed * -1;
}
67. Resumen
Cuando manejamos la posición de los objetos en el
juego, es necesario utilizar valores del tipo flotante en.
Hay dos tipos de datos del tipo flotante, el tipo double
que almacena valores con gran precisión, y los del tipo
float.
Cuando escala mostró una imagen es importante
preservar la relación de aspecto.
Todos los tamaños de las imágenes y la ferocidad
tercera calculada basándose en el tipo de pantalla
disponible
68. Verdadero o falso
El tipo float tiene más precisión que el tipo double
El compilador puede quejarse si un programa intenta
colocar un Valor del tipo double dentro de una variable
float
La relación de aspecto de una textura controla que tan
rápido se dibuja en la pantalla.
El método Update debe ejecutar todos los por vientos
de las imágenes y detectar cuando alcanzado una
frontera de pantalla
69. Verdadero o falso
El tipo float tiene más precisión que el tipo double
El compilador puede quejarse si un programa intenta
colocar un Valor del tipo double dentro de una variable
float
La relación de aspecto de una textura controla que tan
rápido se dibuja en la pantalla.
El método Update debe ejecutar todos los por vientos
de las imágenes y detectar cuando alcanzado una
frontera de pantalla
70. Verdadero o falso
El tipo float tiene más precisión que el tipo double
El compilador puede quejarse si un programa intenta
colocar un Valor del tipo double dentro de una variable
float
La relación de aspecto de una textura controla que tan
rápido se dibuja en la pantalla.
El método Update debe ejecutar todos los por vientos
de las imágenes y detectar cuando alcanzado una
frontera de pantalla
71. Verdadero o falso
El tipo float tiene más precisión que el tipo double
El compilador puede quejarse si un programa intenta
colocar un Valor del tipo double dentro de una variable
float
La relación de aspecto de una textura controla que tan
rápido se dibuja en la pantalla.
El método Update debe ejecutar todos los por vientos
de las imágenes y detectar cuando alcanzado una
frontera de pantalla
72. Verdadero o falso
El tipo float tiene más precisión que el tipo double
El compilador puede quejarse si un programa intenta
colocar un Valor del tipo double dentro de una variable
float
La relación de aspecto de una textura controla que tan
rápido se dibuja en la pantalla.
El método Update debe ejecutar todos los por vientos
de las imágenes y detectar cuando alcanzado una
frontera de pantalla