2. Averiguar más acerca de la manipulación y
escala de imágenes cuando se dibuja usando
XNA.
Iniciar la implementación del juego: escalar
imágenes.
Descubrir como escribir métodos en C#
Diseñar programas para que los métodos
creados, puedan ser probados, además de
crear un test para el método.
3. Crear un juego para
mostrar una porción
aumentada de una
imagen.
La imagen luego se
hará más y más
pequeña, es decir
cada vez más visible.
La primera persona
que adivine la
imagen gana.
4. Cuando posicionamos una textura a
visualizar utilizamos un Rectangle, el cual nos
da la posición y tamaño.
El código define un rectángulo, para llenar
completamente la pantalla.
XNA va a escalar la textura para adecuarla al
tamaño definido.
jakeRect = new Rectangle(
0, // X position of top left hand corner
0, // Y position of top left hand corner
GraphicsDevice.Viewport.Width, // rectangle width
GraphicsDevice.Viewport.Height); // rectangle height
5. Esta versión del Update cambia el ancho y
alto del rectángulo utilizado para dibujar a
Jake.
Cada vez que es llamado el ancho y alto del
rectángulo se incrementa
protected override void Update(GameTime gameTime)
{
jakeRect.Height++;
jakeRect.Width++;
base.Update(gameTime);
}
6. El programa muestra a Jake y luego
incrementa el tamaño del rectángulo.
7. El Zoom In del programa, muestra el principio
del comportamiento, pero va en la dirección
errada.
Queremos un juego haga un Zoom Out de un
pequeño detalle, mas que un zoom completo.
Esto significa que debemos con un rectángulo
grande y hacerlo más pequeño.
jakeRect = new Rectangle(
0, // X position of top left hand corner
0, // Y position of top left hand corner
6000, // rectangle width (10 * image width)
4500); // rectangle height (10 * image height)
8. El rectángulo es ahora tan grande que solo
una parte se podrá ver en la pantalla
9. Esta versión del Update cambia el ancho y
alto de un rectángulo usado por Jake.
Cada vez que es llamado el ancho y alto del
rectángulo mostrado es decrementado
protected override void Update(GameTime gameTime)
{
jakeRect.Height--;
jakeRect.Width--;
base.Update(gameTime);
}
10. Es posible modificar
el programa del
zoom in para hacer
un zoom en la
dirección opuesta.
Sin embargo, no
trabaja
apropiadamente
11. El programa provee un
comportamiento del
zoom, pero no es
funcional a como se
requiera.
◦ El zoom es muy lento al
inicio.
◦ El proceso del zoom
parece distorsionar una
imagen.
Será necesario arreglar
este problema
12. Debido a que el camino seguido por la
esquina inferior de la imagen no es la
diagonal de la imagen, la imagen termina
distorsionada
13. Si el cambio de tamaño sigue la diagonal de
la figura, el zoom trabajará de manera
correcta
14. Resulta que lo que deseamos cambiar es el
ancho y alto mediante un porcentaje cada
vez.
Si tomamos el 1% del ancho y alto del
rectángulo cada vez que se actualice, nos
asegura que los cambios serán de manera
apropiada.
Esto nos resuelve el problema de la velocidad
en el cambio de tamaño.
Cuando el rectángulo es muy largo, se
reducirá en un tamaño mayor cada vez
15. Se aconseja crear un método para calcular los
valores de porcentaje para nosotros.
Esto nos permitirá estudiar cómo los métodos
trabajan y cómo podemos crear nuestros
propios y añadirlos en objetos.
Hemos utilizado muchos métodos
proporcionados por los creadores de XNA y C
#, ahora es el momento para crear uno de los
nuestros.
Vamos a llamar al método que crearemos
getPercentage
16. Previamente hemos
visto que un método
tiene un nombre y un
encabezado.
Esta es la manera de
cómo los métodos
Draw y Update han sido
creados.
Ahora vamos a crear el
encabezado para
getPercentaje y escribir
lo que de código para
implementar su
comportamiento
Block of Code
Header
17. se compilará de una
manera correcta, se
ejecutará pero no
hará absolutamente
nada..
Luego vamos a
escribir el código
que permita hacer
los cálculos
respectivos
18. int getPercentage(int percentage, int inputValue)
{
int result = 0;
// TODO: work out the answer and set result to it
return result;
}
Este es el tipo del método.
Queremos que el método retorne un valor
entero, por lo que debemos hacer el método
el tipo entero.
19. Este es el identificador del método.
Describe lo que el método hace, y si retorna
algún valor
int getPercentage(int percentage, int inputValue)
{
int result = 0;
// TODO: work out the answer and set result to it
return result;
}
20. Un parámetro alimenta los valores dentro del
método.
Con los parámetros del método, obtenemos
variables locales que se inicia al valor dado
durante la llamada del método.
La lista de parámetros pueden estar vacía si no
son necesarios.
int getPercentage(int percentage, int inputValue)
{
int result = 0;
// TODO: work out the answer and set result to it
return result;
}
21. El método getPercentage, necesita un
porcentaje dado y un valor para trabajar con
el.
◦ Podemos tener algo como “1% de 800”
Este segundo parámetro provee el valor para
obtener su porcentaje.
int getPercentage(int percentage, int inputValue)
{
int result = 0;
// TODO: work out the answer and set result to it
return result;
}
22. El cuerpo del método es un bloque de código que
actualmente no hace nada..
Podemos declarar y utilizar variables locales.
Debe de tener una sentencia return que devuelve
un resultado
int getPercentage(int percentage, int inputValue)
{
int result = 0;
// TODO: work out the answer and set result to it
return result;
}
23. La sentencia return envía el resultado a donde
fue llamado.
Esta es la manera en la cual el método que ha
sido llamado retorna su resultado.
La palabra return debe estar seguida por un
valor que será enviado.
int getPercentage(int percentage, int inputValue)
{
int result = 0;
// TODO: work out the answer and set result to it
return result;
}
24. Esta es la manera en como este método debe
ser utilizado.
El valor de uno, alimenta el parámetro
percentaje y el valor de height alimenta el
valor inputValue.
Cualquier valor que el método retorna se
restará de height.
Por el momento solamente devuelve cero
height = height - getPercentage(1, height);
25. Cuando un método de llamado, y programa
copia los valores de los parámetros dentro
del método y comienza a ejecutar el código.
Cuando el método finaliza (alcanza la
sentencia return), el valor retronado es
pasado de nuevo y se reanuda la ejecución.
Si el método nunca finaliza, nunca retornará a
donde fue llamado
26. Un método puede ser declarado como void,
como cualquier otro tipo de datos.
Esto significa que método ejecuta una tarea
con y luego no retorna nada.
Los métodos que son declarados del tipo void
no necesita la sentencia return para enviar un
valor, simplemente regresan el control
después de ejecutar su código
27. El código que llama al método, no ha
utilizado el resultado que retorna.
Las dos llamadas que aparece, los valores
que retorna serán ignorados.
getPercentage(99, 100);
getPercentage(50, 300);
28. Esta prueba del método, prueba obtener un
10% de 800
protected override void Draw(GameTime gameTime)
{
if ( getPercentage(10, 800) == 80 )
{
graphics.GraphicsDevice.Clear(Color.Green);
}
else
{
graphics.GraphicsDevice.Clear(Color.Red);
}
base.Draw(gameTime);
}
29. Estas pruebas son un poco más comprensivas
como pero aún no hacen nada.
Desafortunadamente las pruebas pueden
solamente probar la existencia de fallos, sino
que éstas contengan fallos
if ( (getPercentage(0, 0) == 0) && // 0 percent of 0
(getPercentage(0, 100) == 0) && // 0 percent of 100
(getPercentage(50,100) == 50) && // 50 percent of 100
(getPercentage(100,50) == 50) && // 100 percent of 50
(getPercentage(10,100) == 10) ) // 10 percent of 100
{
graphics.GraphicsDevice.Clear(Color.Green);
}
31. Para cambiar las dimensiones de un rectángulo
up durante el método update, es posible cambiar
el tamaño de la imagen cuando el juego se
ejecuta.
Un método c# es creado mediante un
encabezado y un grupo de sentencias que
forman el cuerpo del método.
El encabezado tipo de datos que se retornará, su
nombre y los parámetros.
Un método del tipo void no retorna nada.
Cuando creamos un nuevo método es buena idea
crear algunos datos de prueba.
32. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
33. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
34. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
35. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
36. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
37. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
38. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
39. Un programa XNA fallará si se intenta dibujar una
imagen que no cabe en la pantalla.
Un parámetro alimenta de información la llamada
de un método.
Un método debe de tener al menos 1 parámetro
Un método del tipo void debe retornar un valor.
Si un método es declarado el tipo int el resultado
del retorno será un entero.
Un programa puede ignorar el resultado
retornado por un método.
Un programa puede solamente contener hasta 5
métodos
41. Crear un método de prueba para calcular los
porcentajes.
Descubrir como usar VS para averiguar como
un programa esta pensando.
Aprender mas acerca de cómo ejecutar los
cálculos y como se comportan las variables
enteras y flotantes.
Averiguar como el compilador trata de evitar
cosas erróneas.
Hacer el escalado de la imagen
42. Estos son algunos valores que hemos
probado.
Si trabajan todos, puede ser que la solución
trabaje.
if ( (getPercentage(0, 0) == 0) && // 0 percent of 0
(getPercentage(0, 100) == 0) && // 0 percent of 100
(getPercentage(50,100) == 50) && // 50 percent of 100
(getPercentage(100,50) == 50) && // 100 percent of 50
(getPercentage(10,100) == 10) ) // 10 percent of 100
{Confirmar la configuración de Google Buzz
graphics.GraphicsDevice.Clear(Color.Green);
}
43. Podemos describir como trabaja el porcentaje
de la siguiente manera.
◦ Calcular la fracción que deseamos (este es el
porcentaje, dividido entre 100).
◦ Multiplicar la cantidad por esta fracción para crear
el resultado.
Ahora necesitamos crear algo en C# para que
haga esos cálculos por nosotro
44. Este es una traducción literal del algoritmo.
Ahora probamos este método
int getPercentage(int percentage, int inputValue)
{
int fraction = percentage / 100;
int result = fraction * inputValue;
return result;
}
45. Desde el titulo, podemos deducir que no
funcionaria bien
Que estará pasando
46. Lo que haremos ahora es depurar.
Tenemos un programa que debe trabajar
pero no lo hace.
El algoritmo usado es correcto, pero la forma
que el programa lo implementa es erronea.
Necesitamos ver dentro del programa y
averiguar lo que está haciendo.
Afortunadamente, VS provee algunas
herramientas para ayudarnos a hacer esto.
47. Lo que realmente queremos es una manera
de parar el programa y ver dentro de él.
VS provee una herramienta para esto.
Estas herramientas trabajan con juegos que
se ejecutan en Xbox y Zune.
Hay además una forma profesional para
depurar los programas.
La primera cosa que vamos hacer es colocar
un breakpoint en el programa para detenerlo
en una sentencia particular.
48. Se adiciona un
breakpoint haciendo
clic con el botón
derecho en la
sentencia que se
quiere parar.
Esto adiciona un
punto de color rojo en
la línea.
Cuando de programa
alcanza esta línea la
ejecución se detiene
49. Cuando un programa
alcanza un breakpoint
la ejecución del
programa se detiene..
La sentencia que fue
alcanzada se ilumina.
El programador puede
ahora ver dentro del
programa
50. Es posible ver el contenido de una variable
simplemente colocando el cursor sobre la
variable en el programa..
VS mostrara un pop up con el valor de ella.
Aquí mostramos el valor de la variable
fraction
51. Cuando un programa
es causado por un
breakpoint, VS
provee los controles
que podemos utilizar
para reanudar el
programa.
El botón verde
iniciará la ejecución
del programa de
nuevo
52. Vamos ahora a ver
por que no trabaja a
la perfección
53. La variable fraction es declarada como un
entero.
Esto significa que no puede almacenar un
valor de 0.5 es el cual está funcionando en
este momento.
int getPercentage(int percentage, int inputValue)
{
int fraction = percentage / 100;
int result = fraction * inputValue;
return result;
}
54. Una variable de punto flotante puede
almacenar fracciones.
Necesitamos declarar fraction como float en
lugar de int para poder almacenar el valor
que deseamos.
int getPercentage(int percentage, int inputValue)
{
float fraction = percentage / 100;
int result = fraction * inputValue;
return result;
}
55. Parece como si las variables de punto flotante
pero aún no trabaja a la perfección.
56. Después que la
variable ha sido
creada como punto
flotante el programa
no la compila.
El compilador se
queja acerca de la
sentencia que calcula
el resultado
57. El mensaje de error de el compilador puede
ser un poco difícil de entender.
◦ “Cannot implicitly convert type 'float' to 'int'. An
explicit conversion exists (are you missing a cast?)”
Lo que está diciendo es que no se permite
tomar un punto flotante y colocarlo dentro de
un entero.
Por declaración fraction es flotante, se
pueden hacer calculosque involucren la
variable con resultado flotantes
58. Necesitamos que la variable fraction esté
habilitada para almacenar fracciones por lo
que la declaramos del tipo float.
Esto significa que la expresión
◦ Fraction * inputValue
◦ Genera un valor punto flotante.
El compilador C# no permite colocar un
directamente un valor flotante dentro de un
entero.
Y por lo tanto refuta compilar el programa
59. Cuando C# coloca puntos flotantes dentro de
un entero, se descarta completamente la
parte fraccionaria.
◦ 6.99 se corta a 6.00
◦ Esta es una operación llamada “narrowing”
Esto significa que los datos de pierden, el
compilador no ejecuta esta tarea
automáticamente.
Se necesita decirle explícitamente que el
programador esta de acuerdo con la
operación
int result = fraction * inputValue;
60. Es posible decirle al compilador que se esta
de acuerdo con la conversión, adicionando
algo llamado casting.
◦ El cast expresa el tipo requerido , encerrado entre
parentesis.
Esto le dice al compilador que ejecute la
conversión, y que haga el resultado de la
expresión al tipo que se requiere.
La parte fraccionaria aun esta perdida, pero el
compilado es correcto, por que es
responsabilidad del programador
int result = (int) (fraction * inputValue);
62. En c#, el comportamiento de los operadores
depende de las cosas que están trabajando.
◦ Se ha visto el operador +, el cual lo usamos para
adicionar 2 números o strings.
El operador / es igual.
Cuando lo aplicamos entre enteros, el
resultado es un entero, con la parte
fraccionaria removida.
Este resultado seria 0 en lugar de 0.5
float fraction = percentage / 100;
63. Cuando tenemos una división de punto
flotante, al menos una variable debe de ser
punto flotante.
◦ Esta vez realizamos un cast del valor int al float.
Esto significa que la expresión será evaluada
como punto flotante.
Ahora el método debe de trabajar.
float fraction = percentage / 100;
65. Estas sentencias reducen el largo y ancho del
rectángulo en 1% cada vez que se llama al
método update.
Esto nos brinda un cambio suave y debe
preservar la figura.
jakeRect.Width = jakeRect.Width –
getPercentage(1, jakeRect.Width);
jakeRect.Height = jakeRect.Height –
getPercentage(1, jakeRect.Height);
66.
67. VS provee la ejecución del programa y ver los
valores de las variables.
El compilador no convierte automáticamente
entre diferentes tipos de valores, esto resulta
en pérdida de datos.
Los programadores deben de utilizar cast
para forzar conversaciones entre diferentes
tipos.
El resultado producido por una operación es
pendiente de las cosas con los cuales trabaja
68. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador automáticamente convierte del tipo
flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro
69. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador automáticamente convierte del tipo
flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro
70. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador automáticamente convierte del tipo
flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro
71. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador automáticamente convierte del tipo
flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro
72. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador no convierte automáticamente del
tipo flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro
73. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador no convierte automáticamente del
tipo flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro
74. Un programa colapsa cuando se alcanza un
breakpoint.
No es posible colocar breakpoint en programas
Xna que se ejecutan dentro de una Xbox.
Las variables enteras pueden contener fracciones.
El compilador no convierte automáticamente del
tipo flotante al tipo entero.
El comportamiento de u operador depende de las
cosas por las cuales trabajan.
Un Cast es utilizado para convertir de un tipo a
otro