Mostrando postagens com marcador Jogo. Mostrar todas as postagens
Mostrando postagens com marcador Jogo. Mostrar todas as postagens

quinta-feira, 18 de junho de 2009

Tutorial - Nosso Primeiro Jogo 2D - Parte 6

Neste tutorial veremos, passo a passo, como criar um jogo 2D simples. Este tutorial foi baseado nos vídeos Beginners Guide to 2D Games encontrados no site creators.xna.com.

Esta é a sexta parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio. Aqui veremos como manter e atualizar o controle da pontuação do nosso jogo. Mas antes...

Pesquisando sobre as colisões em jogos 2D, encontrei um método de verificar a colisão por pixel que funciona checando se os pixels de uma imagem intercedem algum pixel de uma outra imagem. Assim podemos tornar nossas colisões mais realistas pois só irão colidir se os pixels das duas imagens entrarem em contato.

Atualizando as Colisões

No nosso arquivo GameObject.cs vamos adicionar um vetor de cores que chamaremos de textureData e que armazenará a informação dos pixels dos nossos objetos.

No arquivo Game1.cs, onde carregamos nossos mísseis, e onde carregamos as aeronaves inimigas, vamos carregar também os vetores de textura de cada um deles.

Agora que temos os dados das texturas de cada imagem, tanto dos mísseis como das aeronaves inimigas, vamos criar no final do arquivo Game1.cs o método IntersectPixels que receberá os retangulos que envolvem duas imagens e suas informações de textura e retornará verdadeiro ou falso caso essas imagens colidam ou não. Esse método também está disponível no site creators.xna.com.

Por último, na função UpdateCannonMissiles(), no trecho em que testávamos a colisão dos mísseis com as aeronaves inimigas, vamos utilizar o método que acabamos de criar.

Se não esquecemos de nada e modificamos tudo direito o projeto deve compilar e rodar sem problemas e agora com colisões mais precisas.

Agora podemos partir para nosso placar. rs.

Criando e Carregando o Arquivo de Definição de Fonte

Para criarmos o nosso controle da pontuação do jogo, precisaremos criar um arquivo que descreverá a fonte que usaremos para escrever algo na tela. Assim, no Solution Explorer, vamos criar uma sub pasta dentro da pasta Content. Clicando com o botão direito na pasta Content, no Solution Explorer, Add->New Folder. Chamaremos essa nova pasta de Fonts.

Após a criação da nossa nova pasta chamada Fonts, iremos clicar com o botão direito nela e Add-> New Item. Aparecerá na tela uma janela para adicionarmos um novo item ao nosso projeto. Selecionaremos adicionar um Sprite Font cujo nome será gameFont.spritefont.

Clicando no botão Add veremos o arquivo gameFont.spritefont ser adicionado ao projeto dentro da pasta em que o inserimos no Solution Explorer e uma nova aba aberta exibindo o conteúdo do nosso novo arquivo. Esse arquivo não é descrito em C# mas em XML que é uma linguagem criada para descrever dados. O nosso arquivo XML está organizado de modo que descreve as informações de nossa fonte.

Faremos algumas alterações nesse arquivo para que fique de acordo com o que desejamos em nosso jogo. Dentro das tags que descrevem o nome da nossa fonte, FontName, iremos colocar o nome da fonte que desejamos utilizar no nosso jogo e que tenhamos no nosso sistema, neste caso usaremos a fonte Arial. Logo abaixo das tags de nome da nossa fonte, temos as tags Size, responsáveis pelo seu tamanho e iremos alterá-la para 18. Feitas essas alterações, podemos salvar nosso arquivo.

Agora iremos ao arquivo Game1.cs e no início do arquivo, logo depois das declarações de variáveis que fizemos para os inimigos vamos declarar mais algumas. A primeira variável que iremos declarar é um inteiro chamado score para computar os pontos que o jogador fizer, logo após iremos declarar uma variável do tipo SpriteFont chamada font que será a representação da nossa fonte e por último um vetor da posição da tela onde nosso placar será desenhado.

Dentro da função LoadContent() iremos carregar com a variável font nossa fonte ao Content Pipeline como fizemos com todas as outras imagens do nosso jogo.

Antes de desenhar nosso placar na tela, vamos verificar como estamos computando as baixas das aeronaves inimigas.

Atualizando a Pontuação a Cada Colisão

No método UpdateCannonBalls() temos um trecho de código que identifica as colisões dos mísseis com as aeronaves inimigas. Dentro da condição que checa essa colisão vamos incrementar a nossa variável score para que ela registre o número de inimigos que derrubamos.


Desenhando o Placar na Tela

Vamos ao método Draw(). Após o trecho de código onde desenhamos nossos inimigos, iremos utilizar o spriteBatch mais uma vez para desenharmos nosso placar. Mas dessa vez utilizaremos sua função DrawString().

Se não nos esquecemos de nenhum detalhe podemos rodar o jogo e teremos nosso placar no canto esquero superior da tela e a cada aeronave que destruimos ele será atualizado.

Resumo

Nesta sexta parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio vimos como adicionar um placar para a contagem de inimigos que acertamos durante o jogo.

Na sétima e última parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio veremos como animar um pouco mais as cenas inserindo explosões realistas a cada colisão.

terça-feira, 28 de outubro de 2008

Tutorial - Nosso Primeiro Jogo 2D - Parte 3

Neste tutorial veremos, passo a passo, como criar um jogo 2D simples. Este tutorial foi baseado nos videos Begginers Guide 2D encontrados no site creators.xna.com.

Esta é a terceira parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio. Aqui veremos como criar e desenhar os mísseis que o canhão do nosso navio irá disparar para acertar as aeronaves inimigas. Veremos também o conceito de array, como declarar uma constante e alguns tipos de loop que a linguagem C# nos oferece.

Adicionando e Inicializando Mais Algumas Variáveis

Para a criação dos mísseis que o nosso canhão irá disparar contra as aeronaves inimigas teremos que adicionar novas variáveis a nossa classe GameObject, no arquivo GameObject.cs. Se esse arquivo não estiver aberto, dê um duplo clique nele no Solution Explorer. Uma das variáveis que iremos adicionar é do tipo Vector2 e a chamaremos de velocity, ela tem o objetivo de armazenar a velocidade do deslocamento do míssil disparado. A segunda variável que iremos adicionar será do tipo bool e a chamaremos de alive, sua função é identificar se o missil ainda está "vivo", ou seja, se ele ainda pode ser vusualizado em nossa tela.


Como fizemos com nossas outras variáveis, vamos inicializa-las no construtor da nossa classe GameObject. Logo abaixo da inicialização da nossa variável center, vamos inicializar nossas variáveis velocity e depois a nossa variável alive. Como tanto o missil como o canhão são objetos do tipo GameObject devemos ter o cuidado de inicializar as variáveis com valores "neutros" que não causem nenhum efeito indesejável no jogo e podemos muda-las mais adiante, fora da classe GameObject, pelo objeto a que pertence. Iremos inicializar a nossa variável velocity como um vetor Zero e nossa variável alive com o valor false.


Instanciando e Carregando Nossos Mísseis

Agora poderemos voltar ao nosso arquivo Game1.cs e declarar na classe Game1, uma constante do tipo int e de nome maxCannonMissiles, que indicará o número máximo de mísseis que poderão aparecer na tela ao mesmo tempo, e um array GameObject[] de nome cannonMissiles, que conterá nossos mísseis. Ao declararmos uma constante usamos antes de seu tipo a palavra reservada const que caso por engano tentemos mudar o valor dessa constante durante a codificação do nosso jogo nos proporcionará erros. O tipo GameObject[] indica um array que nada mais é do que um conjunto de elementos do tipo GameObject organizados de forma sequencial e que podem ser acessados por um indice.


Depois disso vamos até o método protected override void LoadContent() e abaixo de onde inicializamos a posição do nosso canhão vamos instanciar nosso array de mísseis. Esse array terá tamanho maxCannonMissiles. Logo abaixo inicializaremos cada missil utilizando um loop para percorrer o array do início ao fim. Para aqueles que não conhecem, o loop for(,,) funciona da seguinte forma. Fornecemos a ele um inteiro que usaremos como contador que geralmente é o i, depois ele compara o contador com uma condição, que no nosso caso o loop vai acontecer enquanto i for menor que o tamanho do nosso array, e em seguida realizamos um incremento ou decremento do contador, no nosso caso o incrementamos fazendo i++. Quando a condição se torna falsa, no nosso caso quando i for maior ou igual ao tamanho do array o loop é quebrado. Dentro do nosso for vamos inicializando cada elemento do array pelo seu indice cannonMissiles[i] sabendo que o i vai variando de 0 até o tamanho do nosso array.


Atualizando Misseis, Tratando Entradas e Disparos

Tendo instanciado e inicializado nosso array e nossos misseis podemos ir ao método protected override void Update(GameTime gameTime) e dentro dele chamaremos o método UpdateCannonMissiles() logo abaixo do trecho de código onde limitamos a rotação do nosso canhão e acima do base.Update(gameTime).


O método UpdateCannonMissiles() ainda não existe e nós iremos implementá-lo. Nele faremos a atualização da posição de nossos mísseis. Então, no final do método protected override void Update(GameTime gameTime), abaixo da chave que indica seu fim, iremos implementar nosso método. Utilizaremos o loop foreach() que percorre todos os elementos do nosso array sem necessitarmos de um contador. A diferença entre ele e o loop for(,,) é que o foreach() incondicionalmente percorre o array do início ao fim e no for(,,) podemos estabelecer uma condição de parada.


Temos que criar também o método que irá disparar nossos mísseis. Para isso necessitamos de mais duas variáveis na classe Game1 e iremos declara-las logo abaixo de onde declaramos nosso array cannonMissiles. Essas variáveis que iremos declarar são do tipo GamePadState e KeyboardState e usaremos elas para guardar o ultimo estado em que o controle do xbox360 ou o teclado se encontravam a cada quadro.


Podemos voltar ao método protected override void Update(GameTime gameTime) e logo abaixo de onde limitamos a rotação do canhão e acima do método UpdateCannonMissiles() vamos checar se o jogador pressionou o botão A do controle do xbox360 ou a barra de espaço do teclado. Para que fique mais interessante, vamos impedir que hajam disparos continuos caso o jogador mantenha pressionado qualquer um desses botões checando se o estado anterior do botão A do controle do xbox360 ou a barra de espaço era "não pressionado". Caso ele pressione qualquer um desses botões de disparo chamaremos a função FireCannonMissile() que realizará o disparo do missil. Devemos também ao final de tudo atualizar o valor das nossas variáveis de estado do controle e do teclado para que funcionem corretamente a cada quadro.


Vamos agora implementar nosso método FireCannonMissile() logo abaixo do fim do método protected override void Update(GameTime gameTime) e acima do método UpdateCannonMissiles(). Ele verifica se os misseis do nosso array ainda estão na tela, caso algum não esteja podemos disparar outo missil. Assim ele define a posição inicial do missil como sendo a posição do canhão, a rotação da imagem do míssil como sendo a mesma rotação da imagem do canhão (por isso fizemos as duas imagens no mesmo sentido), e a velocidade junto a direção que o missil será atirado.


Temos que fazer uma atualização no método UpdateCannonMissiles() para que possamos "matar" os mísseis que estiverem fora da nossa tela. Logo abaixo de onde atualizamos a posição do nosso missil no método UpdateCannonMissiles() vamos checar se o missil ainda está na tela, o que é uma tarefa bem simples por termos o nosso viewportRect.


Desenhando os Mísseis na Tela

Para finalizarmos temos que desenhar os nossos misseis na tela. Assim no método protected override void Draw(GameTime gameTime), para termos os misseis desenhados antes do canhão e dar a impressão que eles estão saindo de dentro do canhão temos também que colocar o código para desenha-los antes do código para desenhar o canhão. Então usaremos um loop para desenhar cada missil do nosso array na tela.


Se não nos esquecemos de nenhum detalhe e não cometemos nenhum erro podemos rodar nosso jogo e já ver nosso canhão atirando os misseis ao pressionarmos a barra de espaço do teclado ou o botão A do controle do xbox360.


Resumo

Nesta terceira parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio vimos como criar e desenhar os mísseis que o canhão do nosso navio irá disparar para acertar as aeronaves inimigas. Vimos o conceito de array, como declarar uma constante e alguns tipos de loop que a linguagem C# nos oferece.

Na quarta parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio veremos como criar as aeronaves inimigas para que apareçam de posições randomicas do canto direito da tela.

terça-feira, 21 de outubro de 2008

Tutorial - Nosso Primeiro Jogo 2D - Parte 2

Neste tutorial veremos, passo a passo, como criar um jogo 2D simples. Este tutorial foi baseado nos videos Begginers Guide 2D encontrados no site creators.xna.com.

Esta é a segunda parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio. Aqui veremos como criar uma nova classe para representar os outros objetos do nosso jogo. Com essa classe iremos carregar o canhão do navio no nosso projeto. Iremos também desenha-lo na tela e faze-lo girar com os comandos do teclado ou de um controle do xbox360.

Criando e Modificando a Classe GameObject

Vamos criar uma nova classe que representará os objetos do nosso jogo. Vamos clicar com o botão direito do mouse no nó que representa nosso projeto, o Belonave no Solution Explorer, clicando em Add->New Item..., selecionaremos o Template: Class na janela que aparece, daremos o Name: GameObject.cs e clicamos em Add.


Vemos que o XNA Game Studio criou para nós um arquivo praticamente vazio chamado GameObject.cs. Voltaremos então ao arquivo Game1.cs e bem no começo do arquivo temos os using. Iremos copiar todos os using de Game1.cs e coloca-los no lugar dos using que foram criados no GameObject.cs. Como cada objeto que criaremos em nosso jogo tem sua própria imagem, posição, rotação e centro, nós criaremos em nossa classe GameObject essas variáveis. A variável que representa a imagem do objeto será do tipo Texture2D e seu nome sprite, a que representa a posição do nosso objeto será do tipo Vector2 e seu nome position, assim a que representa a rotação do objeto será do tipo float e seu nome rotation e a que representa o centro da imagem é do tipo Vector2 e seu nome center.


Em seguida vamos declarar o construtor da nossa classe GameObject. O construtor é o método que chamamos ao criarmos um novo objeto. Em geral esse método inicializa tudo o que for necessário para a utilização do objeto. No caso do nosso construtor da classe GameObject, além de inicializarmos todos os seus parametros, ele irá receber uma Texture2D que será a imagem do objeto que desejamos desenhar na tela. Iniciaremos a posição como sendo zero, a rotação como sendo zero, atribuiremos a imagem que recebemos a nossa variável sprite e calcularemos o centro tendo esse as coordenadas metade da largura da imagem em X e metade da altura da imagem em Y.


Instanciando, Carregando e Desenhando o shipCannon

Agora vamos voltar ao Game1.cs. Logo abaixo de onde declaramos a backgroundTexture e o viewportRect vamos declarar nossa variável shipCannon, que será o canhão do nosso navio, e é do tipo GameObject.


Iremos inicializa-lo para podermos desenha-lo na tela do nosso jogo. No método protected override void LoadContent(), logo abaixo do Load<>() que fizemos para o backgroundTexture vamos instanciar o shipCannon como um novo GameObject que recebe um Load<>() da imagem do shipCannon e logo após isso vamos inicializar a posição do nosso canhão para posiciona-lo junto ao nosso navio desenhado no backgroundTexture.


Vamos ao método protected override void Update(GameTime gameTime) do Game1.cs, adicionaremos o código necessário para rotacionar o nosso canhão e assim podermos mirar nos nossos inimigos. Como vimos no nosso primeiro tutorial o método Update(GameTime gameTime) é o responsável por atualizar nosso jogo a cada quadro, é nele que codificamos todas as alterações de lógica que queremos fazer em cada objeto do jogo. Vamos adicionar primeiramente o código pare entrada do controle do xbox360 e após o código para entrada do teclado. Esses códigos farão nosso canhão rodar tendo seu centro como eixo. No caso do controle do xbox360, a rotação ocorre de acordo com a variação da alavanca para a esquerda e para a direita. No caso do teclado ocorre quando as teclas da direita ou da esquerda forem pressionadas. O código #if !xbox e #endif faz com que o trecho de código entre eles seja compilado em caso de atender a condição que no caso é ser diferente de xbox. O método Clamp() do MathHelper serve para limitarmos a rotação do nosso canhão.


Para desenharmos o canhão de nosso navio na tela, vamos ao método protected override void Draw(GameTime gameTime) mas não usaremos o mesmo Draw() do spriteBatch que usamos para o backgroundTexture, usaremos um overload do método que aceita outros argumentos. A versão que usaremos nesse caso recebe a imagem, a posição, o retangulo que é um argumento opicional, a cor, a rotação, a origem da rotação, a escala, efeitos e a profundidade.


Se não nos esquecemos de nada e nem cometemos nenhum erro podemos rodar nossa aplicação. Veremos o nosso navio já com seu canhão e esse atende as entradas do teclado e do controle do xbox360.


Resumo

Nesta a segunda parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio vimos como criar uma nova classe para representar os outros objetos do nosso jogo. Instanciamos essa classe e carregamos o canhão do navio no nosso projeto. Também o desenhamos na tela e o fizemos girar com os comandos do teclado ou de um controle do xbox360.

Na terceira parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio veremos como criar e desenhar os mísseis que o canhão do nosso navio irá disparar para acertar as aeronaves inimigas. Veremos também o conceito de array, como declarar uma constante e alguns tipos de loop que a linguagem C# nos oferece.


terça-feira, 14 de outubro de 2008

Tutorial - Nosso Primeiro Jogo 2D - Parte 1

Neste tutorial veremos, passo a passo, como criar um jogo 2D simples. Este tutorial foi baseado nos videos Begginers Guide 2D encontrados no site creators.xna.com.

Esta é a primeira parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio. Aqui vamos rever como criar um novo projeto e como adicionar imagens ao nosso projeto. Vamos ver também como carregar e desenhar na tela uma imagem de fundo no nosso jogo.

No nosso jogo teremos basicamente um navio, seus mísseis e aviões. O objetivo do jogo é, controlando o canhão do navio, conseguir acertar o maior número de aviões que passarem voando na tela.

Criando um Novo Projeto

Primeiramente vamos começar criando um novo projeto. No Visual C# 2005 Express Edition vamos no menu File->New Project..., ou apenas Ctrl+Shift+N. Selecionaremos como Project Type: XNA Game Studio 2.0 e como Template: Windows Game. O Name do projeto eu chamei de Belonave e procurando na Wikipédia temos a seguinte definição: "Belonave é a designação de qualquer tipo de embarcação, fluvial ou marítima, para utilização em combate.", o que tem muito a ver com nosso jogo. Também selecionaremos o Location que acharmos melhor para armazenarmos nosso projeto em nosso PC. Em Solution escolheremos a opção Create a new Solution, deixaremos a opção Create directory for solution marcada e clicaremos em OK.


Salvando as Imagens e Adicionando ao Projeto

Agora que criamos nosso novo projeto, já podemos ver no Solution Explorer os arquivos que o compõem. Ainda não modificaremos nenhum arquivo. Antes vamos baixar e adicionar ao projeto as imagens que usaremos em nosso jogo. Clique em cada imagem abaixo e, com o botão direito do mouse, salve elas em seu PC com os seguintes nomes:

backgroundTexture:

shipCannon:

cannonMissile:

enemyPlane:



Para organizarmos melhor nossas imagens, após telas salvo em nosso PC, vamos voltar ao Visual C# 2005 Express Edition e vamos clicar com o botão direito do mouse em Content, no Solution Explorer, Add->New Folder e nomearems essa nova pasta como Sprites. Mais uma vez na Wikipédia encontramos a seguinte definição: "Sprite é um objeto gráfico bi ou tridimensional que se move numa tela sem deixar traços de sua passagem.". Nessa pasta ficarão armazenadas todas as imagens que usaremos em nosso projeto.
Clicando com o botão direito do mouse na pasta recém criada, no Solution Explorer dentro de Content, Add->Existing Item e vamos ao local onde salvamos nossas imagens. Selecionaremos e adicionaremos cada uma delas.


Carregando e Desenhando a Imagem de Fundo

Depois que já tivermos todas as imagens adicionadas ao projeto na pasta Sprites vamos começar a modificar nosso código. Caso ainda não esteja aberto, abriremos o arquivo Game1.cs clicando duas vezes nele no Solution Explorer. Com o arquivo aberto, procuraremos a classe Game1 dentro dele. Abaixo de GraphicsDeviceManager graphics; iremos declarar a variável que será responsável pela imagem de fundo do nosso jogo. Essa variável será do tipo Texture2D e se chamará backgroundTexture. Abaixo de nossa variável backgroundTexture vamos declarar outra variável, que será responsável por definir a área máxima que um objeto poderá ter. Esta será do tipo Rectangle e a chamaremos de viewportRect. Essas variáveis que acabamos de declarar ficaram acima do SpriteBatch spriteBatch; que é uma classe do XNA framework que utilizaremos para desenhar todas as imagens que usamos nesse tutorial.


Para carregarmos nossa imagem de fundo no nosso jogo, vamos ao método protected override void LoadContent() que como vimos em nosso primeiro tutorial, é um método que é chamado quando o jogo inicia e ele carrega todas as imagens que precisamos durante o jogo. Logo abaixo de spriteBatch = new SpriteBatch(GraphicsDevice); vamos carregar nossa imagem de fundo na nossa variável backgroundTexture. Para isso vamos usar o método Load<>() da classe Content Manager.


Ainda no método protected override void LoadContent(), abaixo da atribuição que acabamos de fazer para carregar nossa imagem de fundo, vamos instanciar nosso viewportRect atribuindo a ele as nossas medidas da tela começando em (0, 0) e termonando em (width, height) da Viewport.


Agora que a carregamos, desenharemos a nossa imagem de fundo na tela. Para isso usaremos a classe SpriteBatch spriteBatch; e nosso Rectangle viewportRect; que acabamos de inicializar. Vamos então ao método protected override void Draw(GameTime gameTime). Como vimos no nosso primeiro tutorial o método Draw() é o responsável por redesenhar a tela a cada quadro. É nele que a tela é limpa e que desenhamos cada objeto que desejamos que apareça no nosso jogo. Abaixo do graphics.GraphicsDevice.Clear(Color.CornflowerBlue); vamos acrescentar o bloco que nos permite desenhar na tela.
Iniciamos com o método Begin() do spriteBatch, desenhamos com o método Draw() do spriteBatch e ao terminarmos finalizamos com o método End() do spriteBatch. No método Begin() podemos passar como parametro o SpriteBlendMode.AlphaBlend que nos permite desenhar imagens com transparencia. No método Draw() iremos passar como parametros nossa textura, um retangulo que especifica onde a sprite será desenhada, e uma cor que por default estamos usando o branco. O método End() não recebe parametros.


Se não tivermos esquecido de nada, podemos rodar nossa aplicação sem erros e conseguiremos ver a janela do nosso jogo já com a nossa imagem de fundo no lugar.


Resumo

Nesta primeira parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio revimos como criar um novo projeto e como adicionar imagens ao nosso projeto. Vimos como carregar e desenhar na tela uma imagem de fundo no nosso jogo.

Na segunda parte do nosso tutorial de como criar um jogo 2D com o XNA Game Studio veremos como criar uma nova classe para representar os outros objetos do nosso jogo. Com essa classe iremos carregar o canhão do navio no nosso projeto. Iremos também desenha-lo na tela e faze-lo girar com os comandos do teclado ou de um controle do xbox360.