
Continuando a explicar o conceito de Scenes, vimos como o Game1 trabalha com as scenes. Vamos agora ver como é a implementação dentro da Scene.
A classe base Scene é bastante simples. Ela é uma classe abstrata, o que significa que você não pode utilizá-la diretamente. A única maneira de utilizar é extendendo a classe com o uso de herança. Por quê? Porque nela temos somente a estrutura básica, mas a implementação de cada scene depende do contexto do jogo. Aà sim criamos uma nova classe herdada dela, como por exemplo SceneTitle ou SceneAction.
Veja o código de Scene:
Como já falei, temos uma lista de fontes e uma lista de sprites. A classe Font assim como Sprite é também uma criação minha, que encapsula coisas mais chatas do framework.
Outra coisa que temos é uma cor de fundo em BackgroundColor, que a scene vai armazenar e o Game1.Draw() vai utilizar para pintar todo o buffer. Para quem não sabe, antes de pintar sprites na tela, o buffer é todo zerado com uma cor única, para limpar a sujeira toda dos Draws anteriores e começar do zero. Geralmente a cor padrão é preto, mas dependendo da tela você pode usar outra cor. Na tela de partida do jogo eu uso cinza, porque cada pedaço do HUD do jogo fica um pouco afastado do outro e o cinza acaba se destacando entre esses pedaços, simulando uma pequena borda:
A bordinha cinza na verdade faz parte do fundo cinza, e sobrou porque todo o resto foi pintado por cima, sobrando somente esses filetes entre os painéis do HUD.
Por padrão eu carrego a cor preta. Mas em qualquer lugar, a qualquer momento é possÃvel trocar a cor.
Uma coisa necessária paar que a scene recém-criada possa ter seus sptires e fontes carregados pelo Game1, eu uso a linha de código no construtor:
Globals.MustLoadContent = true;
O Game1.Update() verifica o valor e se estiver true, volta para o Game1.LoadContent(). Senão, continua fazendo o update:
O que isso significa é que todas as vezes que crio uma nova scene (e imaginando que a utilizarei imediatamente) o jogo vai parar de rodar a scene anterior e carregar novamente os sprites desta nova scene. Assim que tudo carrega, faço isso:
Globals.MustLoadContent = false;
Algo tosco e básico, mas altamente inteligÃvel ("entendÃvel"). Não gosto de implementações que usam conceitos avançados de orientação a objeto porque fica muito difÃcil de entender o que está acontecendo. Na verdade a orientação a objetos serve justamente para esconder código e facilitar/segmentar o desenvolvimento de sistemas. Aqui a idéia é ser didático, então tudo tem que ser simples.
Veja a implementação completa de SceneTitle, referente à primeira tela do jogo, com o menu principal e o tÃtulo:
Como o código de Update() ficaria muito extenso, eu cortei parte dele, pois aqui o objetivo é entender como implementar uma scene inteira.
No LoadSpriteList() eu instancio os sprites que utilizarei e adiciono cada um na lista. Faço o mesmo com as fontes no método LoadFontList().
No caso dos sprites, os 3 únicos utilizados aqui são a figura que ilustra a tela, o cursor de seleção e a figura da nave atualmente selecionada. Como o sprite da nave selecionada eu utilizo durante todo o jogo, eu não preciso declarar este objeto na scene. Eu declaro em Globals. Por isso só existem essas duas declarações de sprite:
private Sprite titleScreen;
private Sprite cursor;
Porém, ao carregar os sprites que serã0 utilizados na scene, eu carrego junto com os dois anteriores o sprite da nave que está lá no Globals:
this.SpriteList.Add(this.titleScreen);
this.SpriteList.Add(this.cursor);
this.SpriteList.Add(Globals.SelectedShip);
Veja a tela de tÃtulo:
Com isso encerramos este tópico sobre scenes.
Parte 4 - Scenes
Parte 6 - Audio
Tags: Desenvolvimento, XNA, XNA Lander
Categorias: Desenvolvimento | No Comments »