Você está na página 1de 37

XNA Game Studio 2.

0
Aula 1

Novidades e rede

Alexandre Santos Lobão


contato@AlexandreLobao.com

Pós em Desenvolvimento de Jogos Eletrônicos - IESB


Agenda: Aulas 1 e 2
O que há de novo no XNA 2.0
Criação de jogos multiplayer
Definição da topologia
Definição do tipo de jogo
Dicas importantes
Jogos Multiplayer com XNA
Principais componentes
Fazendo Sign-in
Criando uma sessão
Buscando uma sessão
Iniciando um jogo
Enviando e recebendo mensagens
2
Antes de começarmos...
Assunto para próximas aulas
Temos mais 5 aulas depois destas
Possíveis tópicos
Estendendo a content pipeline
Uso de som 3D
Performance / multithreading
Outros tópicos avançados
Deploy para XBox360 e debug (voluntários para ceder a máquina?)
Projeto final (?)
Over-overview do DirectX 9 (10 é só para Vista) com C++
Sugestões?
Avaliação
?? Sugestões ??
3
O que há de novo no XNA 2.0
Não é mais “XNA Game Studio Express”
O “Express” deixou de existir, funciona no Visual
Studio 2005 - mas ainda (oficialmente) não no
2008
XNA Game Studio Device Center
Permite gerenciar conexões com múltiplos Xbox, a
partir da chave de conexão do XNA Game Studio
Novo formato de projeto
Precisa rodar o “Upgrade Wizard” para projetos
antigos

4
O que há de novo no XNA 2.0
XNA Game Studio Package Utility
Novo formato de “pacote” (utilizado para envio e
distribuição de jogos)
Nova versão do XACT
Som 3D, efeito doppler, propriedades melhor
organizadas, etc
“Content” como projeto integrado
Não é necessário mais criar objeto do tipo
“ContentManager”
Fica mais fácil trabalhar (e debugar) extensões da
content pipeline
5
O que há de novo no XNA 2.0
Processadores de conteúdo com parâmetros
Mais flexibilidade no desenvolvimento de
processadores para a content pipeline
Novo processador de texturas
SpriteTextureProcessor e ModelTextureProcessor
fundidos no TextureProcessor

6
O que há de novo no XNA 2.0
Novas propriedades da classe Game
GraphicsDevice e Content

Novos métodos da classe Game


LoadContent e UnloadContent (versão simplificada, e
mais poderosa, dos similares da versão anterior)

Diversos novas funcionalidades na parte de


gráficos e matemática
Inclusive um método para transformar boundingspheres,
que com isso passam a ser úteis!

7
O que há de novo no XNA 2.0
Novidades na parte de input (GamePad)
Enumeração gamePadType permite verificar o tipo
de controle, e método GetCapabilities permite
receber detalhes sobre capacidades.
ArcadeStickController - arcade stick.
DancePadController - dance pad.
DrumKitController - drum kit (tambor).
FlightStickController - flight stick (manche).
GamePadController - Xbox 360 Controller.
GuitarController - guitarra!
UnknownController - unknown type (?)
WheelController – wheel (volante).
8
O que há de novo no XNA 2.0
Novo objeto Guide: pode mostrar guias do
XBox 360 (incluindo no Windows)
LIVE! (ShowSignIn, ShowFriends, ShowGamerCard,
etc)
Teclado (BeginShowKeyboardInput)
Dispositivo de armazenamento
(BeginShowStorageDeviceSelector)
Mensagem (BeginShowMessageBox)

9
O que há de novo no XNA 2.0
Suporte a rede!
Conexão entre Xbox 360 e PC
Conexão local e via LIVE!
Inclui suporte a LIVE! MatchMaking
Conecta você a pessoas com perfil semelhante

Funcionalidade “mais esperada”


É o que vamos estudar nos próximos slides
Ainda falta capacidade de compartilhar jogos!

10
Criação de jogos multiplayer

Jogos em rede são complicados


Embora o XNA facilite…

Precisamos entender alguns


conceitos básicos:
Definição da topologia
Definição do tipo de jogo
Dicas importantes
11
Definição da topologia
XNA não faz nenhuma restrição
Tipos mais comuns em jogos:
Ponto-a-ponto

Cliente-servidor

12
Definição da topologia
Mas podemos ser criativos!
Topologia em anel

Ligação por grupos

13
Definição do tipo de jogo
Em turnos ou real-time?
Real-time pode sofrer com lag da rede
Em turnos suporta poucos jogadores

Onde é realizado o processamento?


No servidor (se houver) ou no cliente?

O que será passado entre máquinas?


Quanto menos dados forem passados, mais
processamento em cada máquina será requerido
14
Dicas importantes
Planeje antes de começar a codificar!
Mensagens de rede são naturalmente assíncronas,
e o jogo tem que prever isso
Se possível, codifique para rede desde o início
Adaptar um jogo para funcionar em rede pode ser
mais difícil e ter resultados ruins!
Defina cuidadosamente as mensagens
Detalhe tipo e conteúdo de cada mensagem

15
Dicas importantes
Esconda a latência da rede!
Latência será sempre um fato, e é imprevista
Planeje seu jogo para que não “trave” esperando
mensagens de rede
Mostre alguma ação, ajuste depois se necessário

XNA oferece métodos para simular latência e


perda de pacotes para teste!
NetworkSession.SimulatedLatency e
NetworkSession.SimulatedPacketLoss

16
Dicas importantes
Inclua funcionalidades single-player em seus
jogos multiplayer!
Um jogo pode ser excepcional jogando em rede,
mas não deixe de fora os jogadores que gostam de
jogar sozinhos!
Use threads diferentes para gerenciar rede, se
possível
XNA oferece funções específicas para multithread
no Xbox 360
Teste, teste, teste
Com jogos em rede, nunca é demais!
17
Jogos Multiplayer com XNA
Principais componentes
Guide, GamerServices e GamerServicesComponent
Fazendo Sign-in
Criando uma sessão
Buscando uma sessão
Sincronamente
Assincronamente
Iniciando um jogo
Enviando e recebendo mensagens
Garantia de entrega e ordem
Envio de pacotes
Leitura de pacotes
18
Jogos Multiplayer com XNA
Passos no Host:
Executar sign-in
Criar Sessão (abrir um “Lobby”)
Esperar jogadores conectarem e informarem que
estão prontos (“ready”)
Iniciar jogo (sair do “Lobby” para o jogo)
Trocar mensagens durante o jogo
Terminar jogo (sair do jogo)

19
Jogos Multiplayer com XNA
Passos nos clientes:
Executar sign-in
Procurar uma Sessão com slots disponíveis
Conectar-se à sessão (entrar no “Lobby”)
Informar que está pronto para iniciar (“ready”)
Conferir status para saber quando jogo começou e
terminou
Trocar mensagens durante o jogo

20
Principais Componentes
Namespaces:
Microsoft.Xna.Framework.GamerServices
Microsoft.Xna.Framework.Net
Guide
Acesso fácil ao XBox / Games for Windows LIVE! Guide
Guide.ShowSignIn(1, false);
Parâmetros:
- número de painéis (sempre 1 para windows)
- se deve mostrar apenas profiles on-line
GamerServices
Acesso fácil aos serviços de rede através do
GamerServicesComponent
Components.Add(new
GamerServicesComponent(this));
21
Fazendo Sign-in
Após incluir o GamerServicesComponent,
basta pressionar a tecla <Home>

Via programa, podemos usar o Guide para


invocar a guia de sign-in. Por ex:
if (Keyboard.GetState().IsKeyDown(Keys.S))
if (!Guide.IsVisible)
Guide.ShowSignIn(1, false);

Importante: O Games for Windows – LIVE! Só


suporta uma conexão por máquina, então, para
testes precisamos de duas máquinas separadas! 22
Criando uma sessão
Para criar uma sessão, basta 1 linha:
private NetworkSession session = null; // The game session
private int maximumGamers = 2; // Only 2 will play, 31 max
private int maximumLocalPlayers = 1; // no split-screen
public void CreateSession()
{
if (session == null)
session = NetworkSession.Create(
NetworkSessionType.SystemLink,
maximumLocalPlayers, maximumGamers);
}

Importante: É obrigatório chamar o “update” da


sessão no “update” da classe Game1
if (session != null)
session.Update();
23
Criando uma sessão
Tipos de sessão:
NetworkSessionType.Local: sem rede, usada para
jogos com split-screen – só funciona no XBox 360
NetworkSessionType.SystemLink: conecta duas
máquinas, XBox 360 ou PC, na mesma subrede
NetworkSessionType.PlayerMatch: conexão tipo
PlayerMatch via LIVE!
NetworkSessionType.Ranked: usada para jogos
comerciais que usam ranking, que passaram pela
certificação do XBox LIVE.

24
Criando uma sessão
Algumas propriedades importantes:
AllowHostMigration: para jogos ponto-a-ponto, permite um novo
jogador assumir como host caso o host saia do ar
AllowJoinInProgress: permite jogadores entrarem em jogos em
andamento
Eventos da sessão:
GamerJoined: Um jogador entrou no jogo
GamerLeft: Um jogador saiu do jogo
GameStarted: O jogo iniciou (conforme comando do host)
GameEnded: O jogo terminou (idem)
SessionEnded: A sessão terminou (inclui motivo como parâmetro)
HostChanged: indica aos jogadores que um novo host assumiu
Associando um evento ao objeto de sessão:
session.GamerJoined += new
EventHandler<GamerJoinedEventArgs>(session_GamerJoined);

25
Buscando uma sessão
Sincronamente
Passo 1: Busca todas as sessões com determinadas
características (tipo, número de jogadores locais, e
propriedades específicas)
public void FindSession()
{
AvailableNetworkSessionCollection availableSessions;
AvailableNetworkSession availableSession = null;
availableSessions = NetworkSession.Find(
NetworkSessionType.SystemLink,
maximumLocalPlayers, null);

26
Buscando uma sessão
Sincronamente
Passo 2: Verifica se nas sessões encontradas há
alguma com slots livres
foreach (AvailableNetworkSession curSession in
availableSessions)
{
int TotalSessionSlots =
curSession.OpenPublicGamerSlots +
curSession.OpenPrivateGamerSlots;
if (TotalSessionSlots >
curSession.CurrentGamerCount)
availableSession = curSession;
}

27
Buscando uma sessão
Sincronamente
Passo 3: Conecta à sessão selecionada

if (availableSession != null)
session = NetworkSession.Join(availableSession);
else
session = null;
} // fim da função FindSession()

28
Buscando uma sessão
Assincronamente
Passo 1: Inicia a pesquisa, indicando uma variável para
acompanhar o resultado e o nome da função de retorno
IAsyncResult AsyncSessionFind = null;
public void AsyncFindSession()
{
if (AsyncSessionFind == null)
{
AsyncSessionFind = NetworkSession.BeginFind(
NetworkSessionType.SystemLink,
maximumLocalPlayers, null,
new AsyncCallback(session_SessionFound),
null);
}
}

29
Buscando uma sessão
Assincronamente
Passo 2: Na função de retorno, recupera os
resultados recebidos
public void session_SessionFound(IAsyncResult result)
{
AvailableNetworkSessionCollection availableSessions;
AvailableNetworkSession availableSession = null;

if (AsyncSessionFind.IsCompleted)
{
availableSessions =
NetworkSession.EndFind(result);

30
Buscando uma sessão
Assincronamente
Passo 3: Igual ao síncrono: seleciona sessão com slots
vazios e se conecta!
foreach (AvailableNetworkSession curSession in
availableSessions)
{
int TotalSessionSlots = curSession.OpenPublicGamerSlots
+

curSession.OpenPrivateGamerSlots;
if (TotalSessionSlots > curSession.CurrentGamerCount)
availableSession = curSession;
}

if (availableSession != null)
session = NetworkSession.Join(availableSession);
// Reseta a variável de acompanhamento da busca
AsyncSessionFind = null; 31
Iniciando o jogo
O objeto session possui diversos estados:
NetworkSessionState.Lobby: Jogadores se conectaram,
mas o jogo não foi iniciado pelo host
Host consulta session.IsEveryoneReady para
saber se pode iniciar o jogo
Jogadores informam que estão prontos
foreach (LocalNetworkGamer gamer in
session.LocalGamers)
gamer.IsReady = true;
NetworkSessionState.Playing: Jogo em curso – host
chamou session.StartGame()
NetworkSessionState.Ended: Jogo terminou (host chamou
Session.EndGame()
32
Enviando e recebendo mensagens

Métodos da classe LocalNetworkGamer:


SendData
ReceiveData
Parâmetros:
Dados (arrays de bytes ou stream gerado pelos
objetos PacketWriter e PacketReader)
SendDataOptions
None: pacote enviado sem garantias
InOrder: ordem de envio dos pacotes é mantida, mas pode perder
pacotes
Reliable: pacotes nunca são perdidos, mas podem chegar fora de
ordem
ReliableInOrder: sem perda de pacotes, pacotes sempre em ordem
33
Enviando mensagens
PacketWriter packetWriter = new PacketWriter();
public void SendMessage(string mensagem)
{
foreach (LocalNetworkGamer localPlayer in
session.LocalGamers)
{
packetWriter.Write(mensagem);
localPlayer.SendData(packetWriter,
SendDataOptions.None);
}

34
Recebendo mensagens
PacketReader packetReader = new PacketReader();
public string ReceiveMessage()
{
String Mensagem = String.Empty;
NetworkGamer remotePlayer;

foreach (LocalNetworkGamer localPlayer in


session.LocalGamers)
{
while (localPlayer.IsDataAvailable)
{
localPlayer.ReceiveData(packetReader,
out remotePlayer);
if (!remotePlayer.IsLocal)
message = packetReader.ReadString();
}
}
} 35
Desafio
Em grupos (20 minutos)
Definir jogos simples multiplayer
Forca? Jogo da Velha? Pong?
Definir mensagens a serem trocadas e “diagrama de
seqüência” – quando serão trocadas
Descrever jogabilidade, telas, etc, simplificadamente

Com o professor (1 hora)


Exercício prático: criar classe “NetworkHelper”

Em grupos (2 horas)
Implementar jogo usando a classe NetworkHelper

36
Perguntas?

37

Você também pode gostar