Вы находитесь на странице: 1из 44

XNA Game Studio Express

Aula 2

Desenho em 2D

Alexandre Santos Lobo


contato@AlexandreLobao.com

Ps em Desenvolvimento de Jogos Eletrnicos - IESB

Agenda: Aula 2
Reviso Arquitetura de um programa XNA Desenho em 2D Components de um game Tratamento de input do usurio Diviso dos grupos para o projeto da matria

Reviso - XNA Game Studio Express


XNA Game Studio Express
XNA Game Studio Express Extends C# Express to support XNA Framework, building game content and targeting Xbox 360 XNA Framework .NET Game Framework .NET Framework for 360 Customized .NET Compact Framework

XNA FrameworkXNA Framework

Reviso: XNA Framework


Games Starter Kits Cdigo Contedo
Componentes

Extended Framework

Application Model

Content Pipeline

Core Framework

Graphics

Audio

Input

Math

Storage

Plataforma

Direct3D

XACT

XINPUT

XContent

Legenda

XNA Provides

Ns criamos

Comunidade

Arquitetura de um programa XNA


Ao se criar um projeto, so gerados dois arquivos: Program.cs Game1.cs

Arquitetura de um programa XNA


Program.cs
static void Main(string[] args) { using (Game1 game = new Game1()) { game.Run(); -> Executa o Game Loop } }

ClasseGame
a central da arquitetura XNA Tem, internamente, um game loop chamado a cada 1/60 de segundo (default) Propriedade TargetElapsedTime pode mudar esta velocidade

is 1/60th of a second.

Arquitetura de um programa XNA


Game1.cs
Construtor cria os objetos Graphics e Content
public Game1() { graphics = new GraphicsDeviceManager(this); content = new ContentManager(Services); }

Mtodos chamados pela classe Game (Eventos do jogo)


Initialize() LoadGraphicsContent(bool loadAllContent) UnloadGraphicsContent(bool unloadAllContent) Update(GameTime gameTime) Draw(GameTime gameTime)
8

Arquitetura de um programa XNA


Mtodos chamados pela classe Game (1/2)
Initialize()
Chamado quando o jogo carrega Onde se inicializam os recursos no grficos
Por exemplo, Mousehelper, Som, etc

LoadGraphicsContent(bool loadAllContent)
Chamado sempre que necessrio carregar os recursos (contedos) grficos
Isso pode acontecer no incio do jogo, ou quando a janela (no Windows) sai de trs de outra janela, ou quando por algum erro se perde a referncia ao dispositivo (device) de video

Quando LoadAllContent true, necessrio recarregar todo o contedo (jncluindo os marcados como modo de gerenciamento de recursos automtico). Mais sobre o modo de gerenciamento de recursos no prximo slide

Arquitetura de um programa XNA


O Modo de gerenciamento de recursos
usado nos mtodos LoadGraphicsContent e UnloadGraphicsContent passado como parmetro ao carregar vertex buffers, index buffers, textures, e surfaces) pode ser manual ou automtico Se for Manual, os recursos precisam ser recarregados sempre que se perder a referncia ao device Se for Automtico, sero automaticamente gerenciados pelo sistema, existindo para a aplicao quase sempre (o XNA carrega para a memria caso necessrio e j no esteja carregado) No gerenciamento automtico, o XNA fica livre para liberar os recursos na memria da placa caso precise deles, recarregando quando a aplicao necessitar. O Gerenciamento Automtico o default, e o usado pela maioria das aplicaes.
10

Arquitetura de um programa XNA


Mtodos chamados pela classe Game (2/2)
UnloadGraphicsContent(bool unloadAllContent)
Chamado sempre que necessrio liberar os recursos (contedos) grficos Quando LoadAllContent true, necessrio descarregar todo o contedo

Update(GameTime gameTime)
Chamado a cada game loop Onde se coloca a lgica principal do jogo (clculos) Recebe um objeto (gameTime) com uma foto com informaes sobre o tempo no instante da chamada do mtodo Mais sobre gameTime no prximo slide

Draw(GameTime gameTime)
Chamado a cada game loop Onde se colocam as rotinas de desenho do jogo

11

Arquitetura de um programa XNA


GameTime Passado como parmetro para os mtodos Update e Draw Tem propriedades que permitem ler o tempo transcorrido desde a ltima chamada e desde o incio do jogo Propriedade IsRunningSlowly indica se o TargetElapsedTime no est sendo atingido O tempo pode se lido em:
Real Time: tempo em segundos reais (relgio)
o usado por quase todas as aplicaes

Game Time: nmero de passos fixos executados conforme o clock da mquina.


Como no reflete o tempo de relgio, a performance de um jogo que se baseie em Game Time pode variar conforme a performance da mquina, caso no se tenha cuidado. Pode ser usado para criar jogos com performance controlvel via programa (possivelmente maior), setando-se a propriedade IsFixedTimeStep do objeto Game para false (executa jogo em full speed, ignorando a propriedade TargetElapsedTime)

Exemplos: gameTime.ElapsedRealTime; gameTime.TotalGameTime;

12

Desenho de objetos 2D

13

Desenho de objetos 2D
Na classe game 1:
private Texture2D textura; private SpriteBatch Renderizador2D;

No Mtodo LoadGraphicsContent:
override void LoadGraphicsContent(bool loadAllContent) { if (loadAllContent) { // Para escolher tamanho da janela ou modo fullscreen: //graphics.PreferredBackBufferWidth = 400; //graphics.PreferredBackBufferHeight = 400; //graphics.IsFullScreen = true; //graphics.ApplyChanges(); textura = content.Load<Texture2D>("xna_thumbnail"); Renderizador2D = new SpriteBatch(graphics.GraphicsDevice); } }
14

Desenho de objetos 2D
No Mtodo UnloadGraphicsContent:
override void UnloadGraphicsContent(bool unloadAllContent) { if (unloadAllContent) { textura.Dispose(); Renderizador2D.Dispose(); content.Unload(); } }

15

Desenho de objetos 2D
No Mtodo Draw:
override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.White); Renderizador2D.Begin(SpriteBlendMode.AlphaBlend); Renderizador2D.Draw(textura, Vector2.One, Color.White); Renderizador2D.End(); base.Draw(gameTime); }

16

Components de um game

17

Components de um game
Coleo Components da Classe Game
Informa ao XNA quais os componentes do jogo Passos para criar um componente:
1. Criar uma classe derivada de GameComponent 2. Criar um objeto desta classe 3. Adicionar o objeto ao Game usando:
this.Components.Add( objeto );

O XNA automaticamente chama os mtodos Update e Draw do objeto, se existirem

18

Components de um game
1. Criar uma classe derivada de GameComponent (1/2)
class clsSprite : GameComponent { public Texture2D textura; // public Vector2 posicao; // public Vector2 velocidade; //

sprite texture sprite posicao on screen velocidade in pixels

public clsSprite(Game game, Texture2D Textura, Vector2 Posicao) : base(game) { textura = Textura; posicao = Posicao; } }
19

Components de um game
1. Criar uma classe derivada de GameComponent (2/2)
public override void Update(GameTime gameTime) { // ajusta a velocidade para no sair pelas bordas da tela if(posicao.X + textura.Width + velocidade.X > this.Game.Window.ClientBounds.Width) velocidade.X = -velocidade.X; // direita if (posicao.Y + textura.Height + velocidade.Y > this.Game.Window.ClientBounds.Height) velocidade.Y = -velocidade.Y; // de baixo if (posicao.X + velocidade.X < 0) velocidade.X = -velocidade.X; if (posicao.Y + velocidade.Y < 0) velocidade.Y = -velocidade.Y; // Atualiza a posio posicao += velocidade; }

//

esquerda

//

de cima

20

Components de um game
2. Criar um objeto desta classe 3. Adicionar o objeto ao Game
private clsSprite Desenho2D; ... protected override void LoadGraphicsContent(bool loadAllContent) { ... // Load a 2D texture sprite Desenho2D = new clsSprite(this, content.Load<Texture2D>("xna_thumbnail"), Vector2.One); Desenho2D.velocidade = new Vector2(1, 2); this.Components.Add(Desenho2D); }

21

Components de um game
Como no fizemos override do Draw, precisamos atualizar o mtodo Draw da classe Game
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.White); Renderizador2D.Begin(SpriteBlendMode.AlphaBlend); Renderizador2D.Draw(Desenho2D.textura, Desenho2D.posicao, Color.White); Renderizador2D.End(); base.Draw(gameTime); }

22

Tratamento de input do usurio

23

Tratamento de input do usurio


Vamos adaptar o demo anterior para incluir um novo objeto, controlado pelo usurio via teclado, gamePad e mouse, atravs dos seguintes passos:
1. Copiar a classe clsSprite e renome-la para clsPlayer 2. Alterar o mtodo Update para tratar o input do usurio 3. Alterar os mtodos do objeto principal (game1) para incluir o novo componente e desenh-lo
24

Tratamento de input do usurio


1. Copiar a classe clsSprite para clsPlayer Dica: use Copy e Paste direto na janela de Solution Explorer do C# Express Alm de renomear, vamos incluir na classe:
using Microsoft.Xna.Framework.Input;

25

Tratamento de input do usurio


2. Alterar o mtodo Update para tratar o input do usurio - GamePad
public override void Update(GameTime gameTime) { Vector2 novaPosicao = posicao; bool podeMover = true; // ser usado para teste das bordas da janela // Muda a posio usando o thumbstick da esquerda GamePadState gamePad = GamePad.GetState(PlayerIndex.One); novaPosicao.X += gamePad.ThumbSticks.Left.X; novaPosicao.Y -= gamePad.ThumbSticks.Left.Y; // Atualiza a posio if(podeMover) posicao = novaPosicao; }
26

Tratamento de input do usurio


2. Alterar o mtodo Update para tratar o input do usurio - Teclado
public override void Update(GameTime gameTime) { ... // muda a posio usando o teclado KeyboardState keyboardState = Keyboard.GetState(); if (keyboardState.IsKeyDown(Keys.Up)) novaPosicao.Y -= 1; if (keyboardState.IsKeyDown(Keys.Down)) novaPosicao.Y += 1; if (keyboardState.IsKeyDown(Keys.Left)) novaPosicao.X -= 1; if (keyboardState.IsKeyDown(Keys.Right)) novaPosicao.X += 1; ... }
27

Tratamento de input do usurio


2. Alterar o mtodo Update para tratar o input do usurio Mouse
public override void Update(GameTime gameTime) {
...

// muda a posio usando o mouse MouseState mouse = Mouse.GetState(); novaPosicao.X = mouse.X; novaPosicao.Y = mouse.Y;
...

28

Tratamento de input do usurio


2. Alterar o mtodo Update para tratar o input do usurio Testando as bordas da janela
public override void Update(GameTime gameTime) { Vector2 novaPosicao = posicao; bool podeMover = true; ... // testa a nova posio para no sair pelas bordas da tela if(novaPosicao.X + textura.Width > this.Game.Window.ClientBounds.Width) podeMover = false; // direita if (novaPosicao.Y + textura.Height > this.Game.Window.ClientBounds.Height) podeMover = false; // de baixo if (novaPosicao.X < 0) podeMover = false; // esquerda if (novaPosicao.Y < 0) podeMover = false; // de cima // Atualiza a posio if(podeMover) posicao = novaPosicao; } 29

Tratamento de input do usurio


3. Adicionar o objeto Player ao Game
private clsPlayer jogador; ... protected override void LoadGraphicsContent(bool loadAllContent) { ... // carrega o jogador jogador = new clsPlayer(this, content.Load<Texture2D>(player_xna_thumbnail"), new Vector2(300, 100)); this.Components.Add(jogador ); }

30

Tratamento de input do usurio


...e finalmente atualizar o mtodo Draw da classe Game
protected override void Draw(GameTime gameTime) { graphics.GraphicsDevice.Clear(Color.White); Renderizador2D.Begin(SpriteBlendMode.AlphaBlend); Renderizador2D.Draw(Desenho2D.textura, Desenho2D.posicao, Color.White); Renderizador2D.Draw(jogador.textura, jogador.posicao, Color.White); Renderizador2D.End(); base.Draw(gameTime); }

31

Tratamento de input do usurio


Toque final: Incluindo deteco de coliso
1. Incluir cdigo na classe Player que testa coliso com objetos Sprite 2. Chamar cdigo na classe principal (game1)
Incluir vibrao no GamePad

32

Tratamento de input do usurio


1. Incluir cdigo na classe Player que testa coliso com objetos Sprite
public bool Colidiu(clsSprite sprite) { // Verifica se colidiu com a sprite if (this.posicao.X + this.textura.Width > sprite.posicao.X && this.posicao.X < sprite.posicao.X + sprite.textura.Width && this.posicao.Y + this.textura.Height > sprite.posicao.Y && this.posicao.Y < sprite.posicao.Y + sprite.textura.Height) return true; else return false; }

33

Tratamento de input do usurio


2. Chamar cdigo na classe principal (game1)
protected override void Update(GameTime gameTime) { ... // Testa se houve coliso if (jogador.Colidiu(Desenho2D)) { Desenho2D.velocidade *= -1; GamePad.SetVibration(PlayerIndex.One, 1.0f, 1.0f); } else GamePad.SetVibration(PlayerIndex.One, 0f, 0f); ... }
34

Desafio 1: Navegao entre telas


Criar uma lista de telas Navegar pela lista de telas

35

Criando uma classe Tela


A tela fcil mais simples que uma sprite!
class Tela { private Texture2D fundo; public Tela(Texture2D Textura) { fundo = Textura; } public void Draw(SpriteBatch Renderizador2D) { Renderizador2D.Draw(fundo, Vector2.Zero, Color.White); } public void Unload() { fundo.Dispose(); } }
36

//

Textura da tela

Navegando entre telas


Tambm fcil basta desenhar uma tela em vez da outra!
... private Tela tela1; private Tela tela2; private Tela telaAtual; ... protected override void Initialize()... Tela1 = new Tela(content.Load<Texture2D>("Tela_Inicial")); Tela2 = new Tela(content.Load<Texture2D>("Tela_GameOver")); telaAtual = Tela1; ... protected override void Update(GameTime gameTime)... if (GamePad.GetState(PlayerIndex.One).Buttons.A==ButtonState.Pressed) telaAtual = Tela2; ... protected override void Draw(GameTime gameTime) ... telaAtual.Draw(Renderizador2D);

37

Dica: E a lista de telas?


No C#, podemos criar listas de objetos com List
Estas listas podem ser acessadas como arrays ou via foreach. Por exemplo:
List<string> palavras = new List<string>(); palavras.Add("Teste1"); palavras.Add("Teste2"); foreach (string palavra in palavras) { MessageBox.Show(palavra); } for(int i = 0; i < palavras.Count;i++ ) { MessageBox.Show(palavras[i]); }
38

Desafio 2: Criar uma lista de botes


Duas imagens: selecionado / no selecionado Com evento que disparado ao executar o boto Criar lista que gerencia navegao entre botes

39

Dica: Input no tem memria


Os objetos de input (Mouse, Keyboard, GamePad) tiram uma foto do estado atual!
No d para saber se o mouse est se movendo, s sua posio No d para saber se o usurio acabou de apertar uma tecla, ou se ela j estava apertada. No d para saber a ltima direo em que o usurio moveu o Mouse ou gamePad => Uso de classes de apoio (helpers)

40

Dica: Input no tem memria


Exemplo de uso de Helpers (classes do Abi, do livro Professional XNA game...:
1. Incluir Input.cs (modificada) no projeto 2. Chamar Input.Update no update do jogo
Input.Update(gameTime);

3. Usar os mtodos (exemplos)


if (Input.KeyboardUpJustPressed) incremento = -1; ... if(Input.GamePadLeftShoulderJustPressed) incremento = -1; ... if (Input.MouseLeftButtonJustPressed) { if (Input.MouseInBox(this[BotaoAtivo].retangulo)) this[BotaoAtivo].Executa(); }
41

Dica: Organizar Projeto!


Atual Organizado

content.Load<Texture2D>(@"Texturas\Botoes\blackBall) content.Load<Texture2D>(@"Texturas\Telas\Tela_Inicial") content.Load<Texture2D>(@"blackBall) content.Load<Texture2D>(@"Tela_Inicial") 42

Diviso dos grupos para o projeto da matria


Mini-GDD em duas semanas

43

Perguntas?

44