XNA Game Studio 2.0 Aula 1 Novidades e rede Alexandre Santos Lobão contato@alexandrelobao AlexandreLobao.com Pós em Desenvolvimento de Jogos Eletrônicos - IESB
Agenda: Aulas 1 e 2 O que há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 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
Oque há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 DeviceCenter 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
Oque há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
Oque há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
Oque há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
Oque há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 GetCapabilitiespermite 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
Oque há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
Oque há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ásicosb 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.SimulatedLatencye 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 threadsdiferentes 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, GamerServicese GamerServicesComponent Fazendo Sign-in 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 slotsdisponí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 Xna.Framework..Framework.GamerServices Microsoft.Xna Xna.Framework.Net Guide Acesso fácil f ao XBox / Games for Windows LIVE! Guide Guide.ShowSignIn ShowSignIn(1, false); Parâmetros: - número de painéis is (sempre 1 para windows) - se deve mostrar apenas profiles on-line GamerServices Acesso fácil f aos serviços de rede através do GamerServicesComponent Components.Add(new GamerServicesComponent(this)); 21
Fazendo Sign-in 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óriochamar 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 oupc, 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, permiteum 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.iseveryonereadypara 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 (arraysde bytes oustreamgerado pelos objetos PacketWriter e PacketReader) SendDataOptions None: pacote enviado sem garantias InOrder: ordemde enviodos pacotesémantida, mas pode perder pacotes Reliable: pacotesnuncasãoperdidos, maspodemchegarforade 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