2. Agenda
Ahora conocemos que un sistema ejecutando XNA
puede tener un host con un lobby que espera por
usuarios a unirse.
Además conocemos el rol de la clase NetworkSession
en la configuración del juego en red.
Ahora vamos a ver como los sistemas son organizados
para el juego en red.
Luego averiguaremos como el juego pasa los datos
entre los sistemas
3. La historia hasta ahora
En la última sesión vimos como usar una maquina de
estado y XNA permite una maquina host en un juego
para buscar juegos y jugar.
Al final de la última sesión teniamos conectados 2
sistemas
Un sistema este en el estado “playingAsPlayer” y el otro
en el estado “PlayingAsHost”.
Ambos juegos tienen una instancia NetworkSession
llamada session la cual representa la conexión entre los
dos juegos
4. El objeto NetworkSession
El objeto NetworkSession
actua como la conexión
entre el juego y la red.
Los juegos XNA
interactúan con su sesión
enviado datos dentro de
la red y recibir mensajes.
Lo que necesitamos saber
es como usar este objeto
para que el juego trabaje.
session
network
session
6. Los objetos en el juego
Existen 3 objetos en el
juego.
Jugador 1: Bread
Jugador 2: Bread
Cheese.
Todo lo que el sistema
necesita conocer es la
posición de cada uno de
esos objetos.
Estos serán pasados a
través de la red
7. Topología de juego
Una topología en este contexto significa “una manera
de organización del sistema”.
Cuando consideramos como sistema un juego,
debemos comunicar. Hay un número diferente de
maneras de organización, cada una con sus ventajas y
desventajas.
Necesitamos considerar esto en el caso que decidamos
expandir nuestro juego para que sean 8 jugdores
8. Topología P2P
Una manera de organizar
el sistema en una red,
puede ser donde cada
sistema envía su
información a cada uno
de los otros.
Este puede resultar en
bastante trafico en la red
entre los sitemas
9. Topología Cliente Servidor
Una mejor manera de
organizar la red es tener
un sistema que actué
como servidor y todos los
demás le envían la
información.
Luego ellos reciben toda
la información desde el
servidor.
Así es como el Xbox Live
trabaja
10. El servidor y el mundo del juego
Si se piensa en como un juego trabajará, hace buen
sentido organizarla en esta manera.
El sistema servidor puede manejar el mundo del juego
y enviar a cada cliente alguna información que permita
al cliente presentar el mundo para jugarlo.
A menudo se da el caso de que el host que propone el
juego termina siendo el servidor de juegos.
Todo esto se oculta al jugar el juego.
11. El cliente y el servidor en el juego
En el juego el servidor moverá la “bola” y detectará el
puntaje.
El jugador en el servidor controlará la bat derecho.
El servidor necesita enviar el cliente.
La posición del bat izquierdo
La posición del cheese.
La cadena de texto del puntaje a mostrar.
Si tenemos más jugadores, se deben enviar también a
ellos esta información
12. La clase XNA PacketWriter
XNA provee una clase llamado PacketWriter que
ensamblará datos en un paquete que pueden ser
enviados a otros sistemas en la red.
Se tiene dentro de ella el método Write que nos da
cada ítem a ser enviado
writer = new PacketWriter();
writer.Write('H');
writer.Write(Cheese.XPos);
writer.Write(Cheese.YPos);
writer.Write(Player1.XPos);
writer.Write(Player1.YPos);
writer.Write(displayMessage);
13. Enviar los paquetes
Los jugadores locales en un sistema puede enviar
datos.
El objeto session almacena la lista de los jugadores
locales.
Obtenemos el elemento al inicio de la lista y llamamos
el método SendData para enviar los datos
empaquetados a todos los sistemas en el juego.
Esto es dicho por el valor PacketWriter junto a las
opciones de envio
14. SendDataOptions
Existe un número de opciones diferentes para enviar
datos.
Chat: el mensaje es parte de un chat entre los jugadores
InOrder: No se garantiza la entrega, pero el mensaje es
recibido en el mismo orden que fue enviado.
None: No garantiza que el mensaje llegue a su dirección
o que llegue en el orden establecido.
ReliableInOrder: Los mensajes se garantizan llegar en el
orden que fueron hechos.
15. Uso de las opciones de
ReliableInOrder
En nuestra versión de juego, usaremos la opción
RealiableInOrder.
Por que nuestro sistema esta en una LAN usando un
SystemLink, no hay mucho trafico.
Si vamos a crear un juego para una gran red, se debe
usar otro tipo de mensaje
16. Envío de pequeños datos de
paquetes
Para minimizar el tamaño
de datos que son
transferidos, se deben
enviar solo los ítems que
son más importantes para
jugar.
En el caso del juego en red
Starlight, se debe enviar las
posiciones de las estrellas
de fondo.
Cada sistema puede dibujar
su propia versión de ellas.
17. Recepción de los datos
El jugador del juego debe enviar la posición del bat
derecho.
Esto es usado por el host para implementar el juego.
El tipo LocalNetworkGamer provee una propiedad
llamada DataAviable que el juego puede ocupar para
probar si algún dato a llegado de la red.
Si tenemos algún dato, podemos usar PAcketReader
para obtener los valores del paquete
18. Recepción de los datos
Los mensajes del jugador inician con la letra “P” y
contienen las 2 coordenadas de posición
while (localHost.IsDataAvailable)
{
NetworkGamer sender;
localHost.ReceiveData(reader, out sender);
char messageType = reader.ReadChar();
if (messageType == 'P')
{
Player2Bat.XPos = reader.ReadSingle();
Player2Bat.YPos = reader.ReadSingle();
}
}
19. El método ReceiveData
El método ReceiveData tiene dos parámetros
Una referencia hacia el lector que es llenado con los
datos que han sido leídos.
Una referencia a una variable llamada sender, que será la
referencia al jugador que envía el mensaje
Por que el método ReceiveData quiere cambiar el valor
de sender, se ha convertido en un parámetro “out”
20. El parámetro out
Se ha visto que los parámetros son pasados
normalmente a los métodos por valor.
Sin embargo, se ha usado la palabra reservada “ref”
para decir que una referencia para pasar al método
una variable y que esta se pueda modificar.
La palabra “out” hace algo similar, pero solamente
permite que el método ReceiveData escriba los valores.
El objetivo es mejorar la confiabilidad haciendo mas
difícil caer en errores
localHost.ReceiveData(reader, out sender);
21. El comportamiento de Update
El comportamiento de la actualización del jugador es
muy similar al del host, pero reservado.
Este envía la posición del bat del jugador 2
Recibe la posición del jugador 1, el cheese y el mensaje
actual del escore para actualizar la pantalla.
Si fueran más jugadores, esto deberá trabajar en la
misma manera
22. Enviando la posición del jugador
Este código crea y envía un paquete que contiene la
posición del bat del jugador.
Es mensaje es prefijado con la letra “P”, para que el
host conozca que esta recibiendo la información del
jugador.
writer.Write('P');
writer.Write(Player2.XPos);
writer.Write(Player2.YPos);
LocalNetworkGamer localPlayer = session.LocalGamers[0];
localPlayer.SendData(writer, SendDataOptions.ReliableInOrder);
23. Enviar la posición del jugador
Este código lee todos los datos enviados al host
while (localPlayer.IsDataAvailable)
{
NetworkGamer sender;
localPlayer.ReceiveData(reader, out sender);
char messageType = reader.ReadChar();
if (messageType == 'H')
{
Cheese.XPos = reader.ReadSingle();
Cheese.YPos = reader.ReadSingle();
Player1.XPos = reader.ReadSingle();
Player1.YPos = reader.ReadSingle();
displayMessage = reader.ReadString();
}
}
24. El método session update
Al final de la actualización del comportamiento del
host o del jugador, se debe llamar al método Update en
la sesión de red.
Esto mantiene a la red en funcionamiento y permite
procesar los mensajes entrantes y entregar cualquiera
que deba ser entregado.
Esto hace que la depuración de los juegos en red sea
complicada, es como un breakpoint que detiene la
ejecución.
session.Update();
25. Mejorando el protocolo
Hasta el momento, los mensajes son enviados usando
una versión de SendData que transmite el mensaje a
todos los sistemas que el juego tiene.
Es posible usar una versión diferente de la llamada que
dirige el mensaje solamente a uno.
Es posible también usar la información el emisario del
mensaje para determinar de donde viene.
Esto permite la creación de mensajes mas avanzados
que permitan usar menos ancho de banda.
26. Demo
Si se usa GamerServicesComponent podemos usar la
tecla Home para abrir la guía
27. Resumen
Una vez los sistemas han establecido una sesión de red
XNA, se puede usar para comunicarse.
Las clases PacketReader y PacketWriter proveen los
medios de ensamblar mensajes que son enviados de un
juego a otro.
Es posible orientar un mensaje a un jugador en
particular, o enviar un mensaje que es recibido por
todos los jugadores en el juego.
Un juego debe llamar al método Update en una sesión
de red para mantener la sesión activa
28. Verdadero o Falso
Una instancia de NetworkSession provee un enlace
entre un juego XNA y una red.
Es imposible enviar un mensaje a mas de un sistema a
la vez.
Es posible enviar solamente valores de punto flotante a
otros sistemas XNA
El PacketWriter es utilizado para decodificar paquetes
que han sido escritos
29. Verdadero o Falso
Una instancia de NetworkSession provee un enlace
entre un juego XNA y una red.
Es imposible enviar un mensaje a mas de un sistema a
la vez.
Es posible enviar solamente valores de punto flotante a
otros sistemas XNA
El PacketWriter es utilizado para decodificar paquetes
que han sido escritos
30. Verdadero o Falso
Una instancia de NetworkSession provee un enlace
entre un juego XNA y una red.
Es imposible enviar un mensaje a mas de un sistema a
la vez.
Es posible enviar solamente valores de punto flotante a
otros sistemas XNA
El PacketWriter es utilizado para decodificar paquetes
que han sido escritos
31. Verdadero o Falso
Una instancia de NetworkSession provee un enlace
entre un juego XNA y una red.
Es imposible enviar un mensaje a mas de un sistema a
la vez.
Es posible enviar solamente valores de punto flotante a
otros sistemas XNA
El PacketWriter es utilizado para decodificar paquetes
que han sido escritos
32. Verdadero o Falso
Una instancia de NetworkSession provee un enlace
entre un juego XNA y una red.
Es imposible enviar un mensaje a mas de un sistema a
la vez.
Es posible enviar solamente valores de punto flotante a
otros sistemas XNA
El PacketWriter es utilizado para decodificar paquetes
que han sido escritos