December 10, 2020 | Author: Anonymous | Category: N/A
Download Desenvolvendo Jogos com o Framework MONOGAME (Free) : Por - Luciano Alves...
Luciano Alves da Silva
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
2
Luciano Alves da Silva
3
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Desenvolvendo Jogos com o Framework
Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Autor: Luciano Alves da Silva
Rio de Janeiro – Outubro/2014
Copyright © 2014 – Todos os direitos reservados 4
Luciano Alves da Silva
5
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Aviso importante Esta obra É UMA VERSÃO DE AMOSTRA, ou seja, UMA VERSÃO LIMITADA E LIVRE da versão COMPLETA. Essa obra , PODERÁ SER DISTRIBUÍDA LIVREMENTE , MEDIANTE AS SEGUINTES REGRAS ABAIXO: Esse material NÃO PODERÁ SER COMERCIALIZADO Essa material NÃO PODERÁ SER DEVIRADO E todos os créditos do autor DEVERÃO SER MANTIDOS
Download dos arquivos Para realizar o download dos arquivos de exemplos utilizados nesta obra, clique no link disponibilizado abaixo:
Link dos materiais http://goo.gl/wqN8jn
6
Luciano Alves da Silva
7
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Sobre o autor da obra Luciano Alves da Silva (
[email protected]) é Bacharelado em Ciência da Computação pela UNISUAM e Pós-Graduado em Docência do Ensino Superior pelo Instituto A Vez do Mestre (Universidade Cândido Mendes UCAM). Possui conhecimento e domínio das linguagens de programação Pascal, Java, C/C++, C#, Visual Basic, Delphi, PHP e HTML. Já criou Ambientes de Desenvolvimento Integrado (conhecidos como IDE) como o MakeWare (que trabalha com as linguagens Pascal, C++ e Java) e o AlgoWare (interpretador de algoritmos). É autor também dos seguintes livros, pela editora AGBOOK
Aprenda Passo a Passo a Programar em Android – Guia Essencial para Desenvolvedores
Desenvolvendo Jogos com a Plataforma XNA – Guia para Desenvolvedores (2ª Edição).
Desenvolvendo Jogos com a Ferramenta RPG Maker VX– Guia do Usuário.
8
Luciano Alves da Silva
9
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Apresentação O mercado de desenvolvimento de jogos tem crescido bastante nesses últimos tempos. Hoje encontramos jogos para as mais diversas plataformas (como PC, Web e Mobile). Atualmente
o mercado de desenvolvimento de jogos para
PC tem ganhado bastante destaque, e hoje temos várias ferramentas (como frameworks) voltados para a criação de jogos
destinados
à
plataforma
PC,
e
uma
dessas
ferramentas e o framework MONOGAME , que é uma plataforma de CÓDIGO ABERTO baseada no XNA da Microsoft. Neste livro você aprenderá nossos básicas de como criar jogos utilizando o framework MONOGAME, através dos seus recursos disponíveis e também através dos exemplos mostrados aqui nesta obra. Para uma abordagem MAIS COMPLETA, adquira a VERSÃO COMPLETA do livro no meu site : http://lucianodev.com
10
Luciano Alves da Silva
11
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Índice analítico
Capitulo 1 Fundamentos básicos sobre jogos ................ 14 1.1) O que é um jogo de computador ? ............................ 14 1.2) Regras para a criação de um jogo ............................. 15 1.3) Sobre a plataforma de desenvolvimento ................. 17 1.4) Sobre a linguagem de programação C#.................... 17 Capitulo
2
Instalando
as
ferramentas
de
desenvolvimento ................................................................ 18 2.1) A ferramenta Xamarim Studio .................................. 18 2.1.1) Realizando o download ........................................... 19 2.1.2) Instalando a ferramenta ......................................... 23 2.2) O framework MONOGAME ......................................... 24 2.2.1) Realizando o download ........................................... 25 2.2.2) Instalando a plataforma ......................................... 26
12
Luciano Alves da Silva 2.3) A biblioteca GameUtil2D ........................................... 30 2.3.1) Para que serve esta biblioteca ? ............................ 31 Capitulo 3 Criando nosso primeiro projeto .................... 32 Capitulo 4 Visualizando imagens no jogo ....................... 50 4.1) Criando nosso projeto ................................................ 50 4.2) Importando a biblioteca GameUtil2D ...................... 50 4.3) Copiando as imagens para dentro do projeto ......... 56 4.4) Desenvolvendo o código............................................. 59 Capitulo 5 Movendo elementos do jogo pela tela ......... 78 Capitulo 6 Trabalhando com animação de sprites........ 93 Capitulo 7 Detectando colisões entre objetos ............ 105 Considerações Finais........................................................ 112
13
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Capitulo 1 Fundamentos básicos sobre jogos
A
ntes de começarmos a estudar e utilizar o framework MONOGAME,
vamos
entender
melhor
os
fundamentos sobre jogos de computador.
1.1) O que é um jogo de computador ? Um jogo de computador (assim como um software que utilizamos no dia a dia), é um programa voltado e destinado somente ao entretenimento e diversão. Praticamente, por parte de muitos usuários, os jogos fazem parte do cotidiano (mesmo para aqueles que não são desenvolvedores). Quem
nunca
se
divertiu (em
seu
momento de intervalo) com algum jogo de computador, por mais simples que seja (como um jogo de campo minado, um jogo de cartas, um jogo de plataforma como Mario Bros e etc.).
14
Luciano Alves da Silva 1.2) Regras para a criação de um jogo de computador Para desenvolvermos um jogo, naturalmente, precisamos ter algumas coisas em mente : seu inicio, meio e fim (história do jogo de modo geral, não importando seu gênero) ; as ferramentas que vamos utilizar para desenvolver os jogos e programadores/artistas que estarão envolvidos no projeto do jogo. Vejamos abaixo algumas imagens de alguns títulos de jogos bastante conhecidos :
Jetpack joyride
15
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Swing Copters
Angry Birds Rio
16
Luciano Alves da Silva 1.3) Sobre a plataforma de desenvolvimento Conforme foi abordado no tópico 1.2 deste capítulo, um dos critérios para a construção de jogos é a ferramenta de desenvolvimento escolhida, que neste caso, será
o
framework MONOGAME. O MONOGAME é um framework de código aberto criado pela Monogame Team , baseado na plataforma XNA da Microsoft. Ele surgiu para dar continuade a plataforma XNA da Microsoft (que foi descontinuada) pertimindo que desenvolvedores criem jogos multi-plataforma (voltados para
Windows,
Android
,
OUYA
e
etc.)
utilizando
praticamente os mesmos comandos e classes que são utilizados no XNA. 1.4) Sobre a linguagem de programação C# A linguagem de programação C# é a linguagem que iremos utilizar para o desenvolvimento de jogos no framework MONOGAME (juntamente com o MonoDevelop (ferramenta de desenvolvimento), hoje mantida pela Xamarim Studio). Caso você , que esteja lendo este livro, não tenha nenhum conhecimento
de
linguagem
de
programação
e/ou
algoritmos, recomendo fortemente o estudo sobre o assunto.
17
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Capitulo 2 Instalando as ferramentas de desenvolvimento
N
este capítulo iremos aprender passo a passo a instalar todas as ferramentas (e frameworks) de desenvolvimento para criarmos os nossos jogos
através do framework MONOGAME. 2.1) A ferramenta Xamarim Studio Conforme já foi mencionado no capítulo anterior, iremos utilizar a ferramenta Xamarim Studio (antigo MonoDevelop) para o desenvolvimento de jogos no MONOGAME. OBSERVAÇÕES SOBRE O XAMARIM STUDIO Durante a produção deste livro já estava disponível a versão 5.0.1.3 da ferramenta Xamarim Studio, porém, por problemas de compatibilidade que esta ferramenta apresentou com o pacote do MONOGAME (voltado para o MonoDevelop), iremos trabalhar com a versão do Xamarim
4.2.2.2,
nenhuma falha.
18
que
apresentou
ESTABILIDADE
e
Luciano Alves da Silva
2.1.1) Realizando o download Para realizarmos o download do Xamarim Studio, visite o seguinte link : http://download.xamarin.com/studio/Windows/XamarinStud io-4.2.2-2.msi Feito isso será aberta a seguinte caixa de diálogo abaixo:
Caixa de diálogo de download
Faça o download do arquivo de instalação do Xamarim Studio, MAS POR ENQUANTO NÃO INSTALE A FERRAMENTA AINDA.
19
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Agora vamos baixar alguns pacotes que funcionam como pré-requisito para o Xamarim Studio. O primeiro deles é a plataforma .NET 4.0, que pode ser baixado no seguinte link abaixo: http://download.microsoft.com/download/9/5/A/95A9616B7A37-4AF6-BC36D6EA96C8DAAE/dotNetFx40_Full_x86_x64.exe
Feito isso será aberto a seguinte caixa de diálogo :
Caixa de diálogo de download Realize o download e faça a instalação do framework .NET 4.0 em sua máquina.
20
Luciano Alves da Silva
Após a instalação do .NET 4.0 vamos instalar agora o GTK# for .NET. Para realizar o download, clique no seguinte link abaixo: http://download.xamarin.com/GTKforWindows/Windows/gtk -sharp-2.12.25.msi Feito isso será aberta a seguinte caixa de diálogo :
Caixa de diálogo de download Após a realização do download execute o programa de instalação do GTK# for .NET. Basta seguir o passo a passo da instalação (praticamente é so clicar Next,...,Next e Install).
21
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Agora vamos realizar o download de um arquivo de instalação muito importante que irá permitir que nossos jogos possam executar no PC, que é a biblioteca “OpenAL” (Open Audio library). Para fazer o download basta clicar no link em seguida : http://goo.gl/53s4yX Feito isso irá se abrir a seguinte caixa de diálogo :
Caixa de diálogo de download
22
Luciano Alves da Silva Efetue o download do arquivo “.ZIP”, e após isso extraia o executável “.EXE” que se encontra dentro do arquivo “zipado”. Em seguida execute o arquivo de instalação. A instalação é muito simples, basta clicar em “OK” para que a biblioteca seja instalada no Windows . 2.1.2) Instalando a ferramenta Depois de instalados todos os pré-requisitos vamos instalar agora a nossa ferramenta Xamarim Studio (que já baixamos anteriormente).
Basta seguirmos passo a passo o
procedimento de instalação (praticamente é só clicarmos em “Next”,..,”Next” e “Install”). Feito isso, vamos executar a nossa ferramenta “Xamarim Studio”. Vejamos nossa ferramenta na figura seguinte:
23
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Ferramenta Xamarim Studio
2.2) O framework MONOGAME Depois de instalarmos o Xamarim Studio, vamos agora instalar o framework MONOGAME.
24
Luciano Alves da Silva
2.2.1) Realizando o download Para realizarmos o download do MONOGAME visite o seguinte link : http://goo.gl/gsa0ow
Caixa de diálogo de download do MONOGAME Efetue o download do MONOGAME é salve o arquivo de instalação em um local apropriado.
25
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] 2.2.2) Instalando a plataforma Agora vamos realizar a instalação do nosso framework MONOGAME no Xamarim Studio. Com o Xamarim Studio aberto, vamos no menu “Ferramentas” e em seguida selecione a opção “Gerenciador de Módulos Adicionais”. Confira a figura em seguida:
Chamando o gerenciador de módulos adicionais
Feito isso irá se abrir a seguinte caixa de díalogo em seguida:
26
Luciano Alves da Silva
Caixa de diálogo – Add-in Manager Agora vamos clicar no botão “Install from file” para buscarmos o arquivo. Feito isso irá se abrir a seguinte tela :
27
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Caixa de diálogo – Install Add-in Package Vamos selecionar o diretório onde se encontra o arquivo que baixamos do MONOGAME, conforme é mostrado em seguida :
28
Luciano Alves da Silva
Selecionando o pacote Agora vamos clicar no botão “Open” para realizarmos a instalação. Feito será mostrada a seguinte caixa de diálogo abaixo:
29
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Feito isso basta clicar no botão “Instalar” para que o pacote seja instalado. Confira o resultado na figura seguinte :
Framework MONOGAME instalado Clique em CLOSE para fechar a caixa de diálogo. 2.3) A biblioteca GameUtil2D Nesta obra , irei utilizar para o desenvolvimento de nossos jogos uma biblioteca (dentro dos nossos projetos no MONOGAME) GameUtil2D.
30
que
eu
mesmo
desenvolvi
chamado
Luciano Alves da Silva 2.3.1) Para que serve esta biblioteca ? Essa biblioteca nada mais é do que um conjunto de classes que facilitam a construção de jogos no MONOGAME. Ela já possui uma série de recursos que facilitam a construção de jogos de forma fácil e rápida (inclui classes para animação de Sprites, colisões, criação de personagens para jogos plataforma e etc.) . Esse framework (que já acompanha este material) pode ser encontrada em seu site oficial : www.gameutil2d.org
31
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Capitulo 3 Criando nosso primeiro projeto
N
este capítulo iremos criar o nosso primeiro projeto de jogo através do Xamarin Studio, usando o framework MONOGAME (em conjunto com as
classes da biblioteca GameUtil2D).
Depois de tudo instalado, vamos executar o Xamarin Studio (indo no “Menu iniciar” / “Todos os programas” / “Xamarin Studio”). Feito o procedimento explicado acima, será aberta a seguinte tela :
32
Luciano Alves da Silva
Xamarin Studio Bom, vamos começar criando nosso primeiro projeto no C# voltado para a PC no MONOGAME. Para isso, vamos no menu “Arquivo” / “Novo” e em seguida “Solução” (ou como tecla de atalho pressione CTRL+SHIFT+N):
33
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Criando um novo projeto Feito isso irá se abrir a seguinte caixa de diálogo a seguir:
Caixa de diálogo – Nova Solução
34
Luciano Alves da Silva Vamos
selecionar
a
seção
“MonoGame”
conforme
demonstra a figura a seguir:
Selecionando a seção “MonoGame” Feito isso veremos várias opções de criação de jogos em “MonoGame”. Como vamos criar jogos voltados para a plataforma PC, vamos selecionar a opção “MonoGame Windows OpenGL Application”. Após selecionar a opção solicitada vamos no campo “Nome” para digitarmos o nome
35
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] do nosso projeto, que vai se chamar “Primeiro_Projeto” (devemos usar “_” ao invés de espaço). Depois disso basta clicarmos em “OK” para que o nosso projeto possa ser criado. Veja na figura seguinte:
Projeto “Primeiro Exemplo” criado
Bom, vamos ver a guia “Solução” para saber quais arquivos compõem um projeto MONOGAME. Confira na figura seguinte:
36
Luciano Alves da Silva
Solution Explorer
Icon.png: Arquivo de ícone , que vai representar a aplicação quando ela for gerada. Game1.cs: Este é o arquivo principal onde nós iremos codificar o nosso jogo. Veja o código fonte dele : #region Using Statements using System; using System.Collections.Generic;
37
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] using Microsoft.Xna.Framework; using Microsoft.Xna.Framework.Content; using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Storage; using Microsoft.Xna.Framework.GamerServices; #endregion namespace Primeiro_Exemplo { /// /// This is the main type for your game /// public class Game1 : Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.IsFullScreen = true; } /// /// Allows the game to perform any initialization /// it needs to before starting to run. /// This is where it can query for any required /// services and load any non-graphic /// related content. Calling base.Initialize will /// enumerate through any components and initialize /// them as well. /// protected override void Initialize() { // TODO: Add your initialization logic here
38
Luciano Alves da Silva
base.Initialize(); } /// /// LoadContent will be called once per game and is /// the place to load all of your content. /// protected override void LoadContent() { // Create a new SpriteBatch, which can be used // to draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game // content here } /// /// UnloadContent will be called once per game and /// is the place to unload all content. /// protected override void UnloadContent() { // TODO: Unload any non ContentManager content // here } /// /// Allows the game to run logic such as updating /// the world, checking for collisions, gathering /// input, and playing audio. /// /// Provides a snapshot of /// timing values. protected override void Update(GameTime gameTime) { if (GamePad.GetState(PlayerIndex.One). Buttons.Back == ButtonState.Pressed ||
39
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Keyboard.GetState().IsKeyDown(Keys.Escape)) Exit(); // TODO: Add your update logic here base.Update(gameTime); } /// /// This is called when the game should draw /// itself. /// /// Provides a snapshot of /// timing values. protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here base.Draw(gameTime); } } }
Irei comentar agora algumas linhas de código do programa acima. Se observarmos dentro da classe Game1 existe dois objetos declarados, conforme você confere abaixo: GraphicsDeviceManager graphics; SpriteBatch spriteBatch;
40
Luciano Alves da Silva A
variável
objeto
“graphics”
é
do
tipo
GraphicsDeviceManager, que representa a janela (tela) onde nosso jogo vai acontecer. A variável objeto “spriteBatch” do tipo SpriteBatch (Lote de imagens) vai armazenar todas as imagens e textos que vão ser exibidas na tela do nosso jogo. Program.cs: Este é o arquivo responsável por carregar o jogo definido em código dentro da classe Game1 . Veja seu código abaixo: #region Using Statements using System; using System.Collections.Generic; using System.Linq; #endregion namespace Primeiro_Projeto { static class Program { private static Game1 game; /// /// The main entry point for the application. /// [STAThread] static void Main () { game = new Game1 (); game.Run (); } } }
41
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Se observarmos o código acima dentro do método Main , existe uma linha de comando que cria a instância da classe Game1, e em seguida, executa todo o seu código através do método Run. Irei comentar agora todo o passo a passo da execução dos métodos
situados
dentro
da
classe
Game1,
para
entendermos como funciona o processo da execução do jogo. Quando a instância da classe Game1 é criada, o primeiro método a ser executado é o construtor da classe, também chamado de Game1, que possui o seguinte código abaixo: graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content"; graphics.IsFullScreen = true;
A primeira linha de código acima cria a instância da classe GraphicsDeviceManager, e atribui essa instância a variável “graphics”. Na linha seguinte defino o diretório padrão de onde serão carregados todos os conteúdos (isso inclui músicas, sons de efeito, imagens, fontes e etc.).
42
Luciano Alves da Silva E na próxima linha, temos uma instrução que irá colocar o jogo em “TELA CHEIA”, através da propriedade IsFullScreen com o valor true. Em seguida, é executado o método Initialize, onde nele podemos iniciar todas as variáveis que serão utilizadas em nosso jogo. Por padrão, esse só possui uma linha de comando que “chama” o método Initialize da classe base (a classe Game). Confira na linha seguinte: base.Initialize();
Em seguida, é executado o método LoadContent, que tem a seguinte linha de código: spriteBatch = new SpriteBatch(GraphicsDevice);
Que cria a instância da classe SpriteBath e em seguida atribui essa instância a variável “spriteBatch”. Este método é utilizado para carregar todo o conteúdo que será utilizado em nosso jogo (como imagens, sons, textos e etc.). Em paralelo, logo após a execução do método acima, são executados os métodos Update e Draw. O método Update serve para colocarmos toda a codificação do nosso jogo, ou seja, e lá que a coisa acontece. Esse método é executado sempre. Veja o código do método Update :
43
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
if(GamePad.GetState(PlayerIndex.One). Buttons.Back == ButtonState.Pressed) Exit(); // TODO: Add your update logic here base.Update(gameTime);
A primeira linha de código acima verifica se a tecla responsável por encerrar o jogo foi pressionada, caso verdadeiro, o jogo termina. Logo em seguida é chamado o método Update da classe base (Game). O método Draw é o responsável por “desenhar” todos os sprites, imagens e textos na tela do jogo. Esse método é executado sempre. Vejamos o código desse método :
GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here base.Draw(gameTime);
Na primeira linha do código acima é disparado o método Clear situado em GraphicsDevice, que “limpa” a tela do jogo com uma cor de fundo especificada no parâmetro. Na linha seguinte é disparado o método Draw da classe base.
44
Luciano Alves da Silva
Executando o nosso projeto Se executarmos o nosso jogo agora ele automaticamente irá colocar o display em TELA CHEIA. Vamos no método construtor da classe Game1 para alterarmos a linha: graphics.IsFullScreen = true;
Por : graphics.IsFullScreen = false;
Vamos agora executar o nosso exemplo seguindo os passos aqui descritos. Para executarmos nosso programa, vamos no menu “Executar” e sem seguida “Start Debugging” ou, simplesmente pressione a tecla F5. Veja o resultado na figura seguinte:
45
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Primeiro exemplo em execução Alterando a resolução da tela do jogo A tela do jogo já está configurada com uma resolução padrão (que é de 800x480), porém, podemos alterar essa resolução de acordo com a nossa necessidade. Vamos criar um novo projeto no XNA chamado “Resolução Tela” para trabalharmos esse exemplo. Se observamos dentro do código da classe Game1 existe um
46
objeto
chamado
“graphics”,
do
tipo
Luciano Alves da Silva GraphicDeviceManager . É através desse objeto que vamos alterar as propriedades de largura a altura da tela. Por exemplo, como faço para colocar a resolução da tela em 300x300 pixels ? Todas essas configurações serão definidas dentro do construtor da classe Game1. Dentro do construtor da classe vamos colocar o código destacado em negrito, conforme você confere em seguida:
public Game1() { graphics = new GraphicsDeviceManager(this); Content.RootDirectory = "Content";
graphics.IsFullScreen = false; graphics.PreferredBackBufferHeight = 300; graphics.PreferredBackBufferWidth = 300; }
A propriedade PreferredBackBufferHeight do objeto “graphics” permite definir a altura da tela do jogo e a propriedade PreferredBackBufferWidth permite definir a largura da tela do jogo. Execute o nosso jogo agora e confira o resultado:
47
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Resolução da tela modificada via programação Agora como faço para obter o tamanho da largura e altura da tela do jogo ? Conforme já havia mostrado, podemos utilizar as seguintes propriedades do objeto “graphics” que são
PreferredBackBufferWidth
e
PreferredBackBufferHeight. Veja um exemplo : int width = graphics.PreferredBackBufferWidth; int height = graphics.PreferredBackBufferHeight;
Também podemos obter a resolução da tela do jogo utilizando o objeto “GraphicsDevice”, como segue abaixo:
48
Luciano Alves da Silva int width = GraphicsDevice.Viewport.Width; int height = GraphicsDevice.Viewport.Height;
A diferença de ambos os meios mostrados para a obtenção da resolução da tela do jogo é que com as propriedades PreferredBackBufferWidth e PreferredBackBufferHeight do objeto “graphics” podemos tanto obter os valores quanto alterá-los. Já as propriedades Height e Width do objeto “GraphicsDevice” são somente leitura.
Nela informaremos nome do projeto (que já foi dado no inicio de sua criação) e local onde salvaremos ele. Feito isso basta clicar em “Save”.
49
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Capitulo 4 Visualizando imagens no jogo
N
o capítulo anterior aprendemos a criar e a executar um projeto (vazio) no MONOGAME , assim como aprendemos também a alterar a resolução da tela
do nosso jogo. Agora vamos começar a colocar a MÃO NA MASSA. Nesse capítulo iremos aprender como visualizar uma imagem na tela (já utilizando a biblioteca GameUtil2D). 4.1) Criando nosso projeto Primeiramente vamos criar o nosso projeto no MONOGAME (com o Xamarin Studio, conforme já foi mostrado no capítulo anterior). O nome do nosso projeto irá se chamar “Visualizando_Imagens”. 4.2) Importando a biblioteca GameUtil2D para o projeto Com os arquivos que acompanham este material já temos a nossa biblioteca GameUtil2D (presente dentro da pasta
50
Luciano Alves da Silva “GameUtil2D”). Agora será necessário copiar todos os arquivos da biblioteca para dentro do nosso projeto. Irei mostrar agora os procedimentos : 1) Com o nosso projeto em MONOGAME criado no Xamarin Studio aberto, clique com o botão direito sobre o nome do nosso projeto e em seguida selecione “Adicionar” / “Adicionar Arquivos” :
Adicionando a biblioteca em nosso projeto Feito isso será aberta a seguinte caixa de diálogo:
51
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Caixa de diálogo – Adicionar arquivos
Agora selecione o diretório onde se encontram os arquivos da biblioteca “GameUtil2D”, conforme é mostrado na figura em seguida:
52
Luciano Alves da Silva
Diretório “GameUtil2D”
Selecione todos os arquivos e em seguida clique em “Open”. Feito isso será aberta a seguinte mensagem :
53
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Mensagem – Add File to Folder Mantenha a opção “Copy the file to the directory” selecionada e a checkbox “Use the same action for all selected files” marcada. Feito isso clique em “OK”. Confira o resultado:
54
Luciano Alves da Silva
Todos os arquivos copiados para o projeto
55
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
4.3) Copiando as imagens para dentro do projeto Da mesma forma que fizemos para importar os arquivos da biblioteca “GameUtil2D” para dentro do nosso projeto, vamos colocar as imagens que vamos trabalhar nesse exemplo. Siga os procedimentos a seguir : 1) Clique com o botão direito sobre a pasta “Content” do nosso projeto e em seguida selecione “Adicionar” / “Adicionar Arquivos” :
Adicionando as imagens em nosso projeto
56
Luciano Alves da Silva Feito isso será aberta a seguinte caixa de diálogo:
Caixa de diálogo – Adicionar arquivos Agora basta selecionarmos o diretório onde se encontra as nossas imagens (o diretório “Capítulo 4”) :
57
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Diretório “Capitulo 4” Feito isso basta selecionar todos os arquivos e clicar em “Open”
(conforme
os
procedimentos
anteriormente). Vejamos o resultado:
58
já
vistos
Luciano Alves da Silva
Imagens copiadas para dentro do projeto 4.4) Desenvolvendo o código Bom, agora vamos desenvolver o código do nosso jogo, que irá mostrar algumas imagens na tela. Primeiramente na seção de declaração (importação) de bibliotecas , presente dentro do código mostrado a seguir :
59
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Seção de declaração de bibliotecas
Vamos digitar a seguinte instrução destacada a seguir :
60
Luciano Alves da Silva
Declarando o uso de nossa biblioteca A biblioteca “gameutil2d.classes.basic” que declaramos agora pouco possui todas as classes básicas do nosso framework “GameUtil2D”, que podemos utilizar para a construção de um jogo. Agora dentro da nossa classe (chamada Game1) vamos digitar o seguinte atributo, conforme mostra a figura seguinte:
61
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Declarando nosso atributo O atributo que declaramos acima (que se chama imagem) é do tipo Image, que é uma classe da biblioteca “GameUtil2D” destinada para a visualização de imagens na tela do nosso jogo. (Para mais informações a respeito de todas as classes do framework, baixe a sua documentação que esta disponível no site do “GameUtil2D”).
62
Luciano Alves da Silva Agora dentro do código do método LoadContent vamos digitar as seguintes instruções, conforme mostra a figura seguinte :
Inicializando nosso objeto Vamos analisar o primeiro comando inserido abaixo. GD.instance = GraphicsDevice;
Aqui nós inicializamos a nossa biblioteca GameUtil2D, guardando a referência do objeto GraphicsDevice para dentro da propriedade instance da classe GD (que será utilizada para carregar as imagens).
63
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Agora vamos analisar a segunda instrução inserida. O construtor da classe Image possui os seguintes parâmetros: O primeiro parâmetro do construtor é padrão, cujo argumento sempre será o “Content”. O segundo parâmetro corresponde à imagem que vamos visualizar no jogo (que é a imagem “bird.png”). Observe que quando informamos o nome da imagem NÃO INFORMAMOS A SUA EXTENSÃO (e também NÃO É PRECISO), pois o MONOGAME já reconhece a imagem presente dentro do projeto.
O terceiro e quarto parâmetro do construtor correspondem , respectivamente, as coordenadas X e Y do objeto na tela do jogo (cujos valores são “0” e “0”). Já o quinto e o sexto parâmetro correspondem, respectivamente, a largura e a altura do objeto (cujo valores são “60” e “47”).
Bom, o que fizemos até agora foi carregar o objeto (imagem) na memória. Agora precisamos desenhar a imagem carregada na tela. Para isso devemos utilizar o método Draw, responsável por essa finalidade. Dentro do método Draw vamos escrever o seguinte código destacado em seguida:
64
Luciano Alves da Silva
Código para visualizarmos a nossa imagem na tela
Vamos analisar o código acima. O método Begin da classe SpriteBatch inicia o objeto para que possamos inserir todo o conjunto de imagens (e também textos, que vamos trabalhar futuramente) que serão exibidos na tela. O método Draw do objeto imagem é responsável por visualizar a imagem na tela , passando como argumento para o método um objeto do tipo SpriteBatch (que nesse caso, é a variável spriteBatch). Na linha seguinte é disparado o método End da classe SpriteBatch, que finaliza a operação o objeto.
65
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Vamos executar a nossa aplicação para conferir o resultado. Possivelmente você verá UMA MENSAGEM DE ERRO, conforme é mostrado na figura em seguida:
Erro ao carregar a imagem CALMA! Não se preocupe. Nosso código não está errado. Precisamos conhecer um pouco das particularidades da ferramenta MONOGAME durante a construção de um projeto. Quando trabalhamos com imagens (contents) em um projeto, por padrão, essas mesmas imagens NÃO SÃO COPIADAS para o diretório do executável do jogo, fazendo com que o erro acima seja exibido.
66
Luciano Alves da Silva Para solucionarmos esse problema, vamos primeiramente selecionar
TODAS
AS
IMAGENS
dentro
do
diretório
“Content”, conforme é mostrado na figura a seguir :
Selecionando todas as imagens
Em seguida, clique com o botão direito sobre as imagens e selecione “Acão de Construção” / “Content”:
67
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Selecionando a opção “Content” O procedimento ainda não acabou. Falta realizar agora a última etapa. Como estamos trabalhando nesse projeto por enquanto com a imagem “bird.png”, clique com o botão direito sobre essa imagem e selecione “Propriedades”. O resultado você confere a seguir:
68
Luciano Alves da Silva
Propriedades da imagem selecionada Agora vamos mudar o valor da propriedade “Copiar para diretório” de “Não copiar” para “Sempre
copiar”. Veja o
resultado na figura seguinte :
69
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Selecionando a opção Antes de executarmos, vamos remover a seguinte linha de código do construtor da classe Game1: graphics.IsFullScreen = true;
Agora compile e execute novamente o projeto e confira o resultado, conforme demonstra a figura seguinte:
70
Luciano Alves da Silva
Imagem sendo visualizada no jogo
E ai, aprendeu como visualizar uma imagem na tela do jogo ? Com certeza que sim! Vamos aproveitar esse mesmo projeto para demonstrar mais um exemplo de visualização de imagens. Vamos voltar para o código de declaração de atributos para digitarmos o seguinte trecho de código destacado em seguida em negrito:
71
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] public class Game1 : Game {
: Image imagem; Image titulo_flappy_bird; Image background_fase_flappy_bird; public Game1()
: Agora dentro do método LoadContent vamos substituir o código destacado abaixo: imagem = new Image(Content, "bird", 0, 0, 60, 47);
Pelo seguinte código destacado em negrito em seguida: protected override void LoadContent() { : imagem = new Image(Content, "bird", 370, 200, 60, 47); titulo_flappy_bird = new Image(Content, "titulo_flappy_bird", 260, 100, 280, 92); background_fase_flappy_bird = new Image(Content, "background_fase_flappy_bird", 0, 0, 800, 480); }
Agora dentro do método Draw vamos digitar o seguinte código, conforme é mostrado em seguida:
72
Luciano Alves da Silva protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); background_fase_flappy_bird.Draw(spriteBatch); titulo_flappy_bird.Draw(spriteBatch); imagem.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
Dentro do método Draw existem três instruções onde cada uma irá exibir uma imagem na tela. As instruções que inserimos no código, possuem uma sequência, que precisarei explicar. Observe que a primeira instrução adicionada no método Draw foi: background_fase_flappy_bird.Draw(spriteBatch);
Que irá exibir uma imagem de fundo, que é a fase do famoso jogo “Flappy Bird”. Em seguida, temos a seguinte instrução: titulo_flappy_bird.Draw(spriteBatch);
73
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Que irá exibir o título “Flappy Bird” na tela. Como essa é a segunda imagem a ser exibida, a mesma é exibida a frente da imagem de fundo. Na terceira instrução temos a seguinte linha de código: bird.Draw(spriteBatch);
Que irá desenhar o “passarinho” (personagem) do jogo na tela. Como essa é a terceira imagem a ser exibida na tela, a mesma é mostrada a frente da imagem de fundo e do título. Antes de executarmos o arquivo, REPITA O MESMO PROCESSO DE “Não copiar” para “Sempre copiar” para os arquivos restantes (“titulo_flappy_bird.png” e “background_fase_flappy_bird.png”), senão será novamente acusado um erro. Executando o nosso código, teremos o seguinte resultado :
74
Luciano Alves da Silva
Resultado do código na tela Invertendo uma imagem na tela A classe Image possui um método chamado Draw que serve para exibirmos uma imagem na tela. Pois bem, o mesmo método possui um segundo parâmetro que nos permite “inverter” a imagem exibida na horizontal. Para realizarmos essa demonstração de inversão de imagem vamos alterar dentro do método Draw, conforme mostra instrução destacada em negrito em seguida:
75
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); background_fase_flappy_bird.Draw(spriteBatch); titulo_flappy_bird.Draw(spriteBatch); imagem.Draw(spriteBatch,true); spriteBatch.End(); base.Draw(gameTime); }
Observe que no objeto bird (que mostra o passarinho na tela), adicionamos o segundo argumento no método Draw, o argumento true (que indica que a imagem será invertida na horizontal). Vejamos o resultado :
76
Luciano Alves da Silva
Imagem invertida na horizontal
Após realizar as modificações solicitadas acima, salve o seu projeto.
77
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Capitulo 5 Movendo elementos do jogo pela tela
N
o capítulo anterior aprendemos como visualizar elementos (como imagens) na tela, porém, as imagens vistas ficam num ponto “fixo” da dela, definido pelo código. Agora vamos aprender a movimentar esses elementos pela tela do jogo usando os recursos oferecidos pela biblioteca “GameUtil2D” no MONOGAME.
Neste capítulo vamos aprender a movimentar os elementos do jogo usando o teclado, através dos métodos oferecidos pelo framework MONOGAME. Primeiramente vamos criar um novo projeto no Xamarin Studio voltado para MONOGAME. O nome do nosso projeto irá se chamar “Movendo_Objetos_pela_Tela”. Depois de criado o projeto copie todos os arquivos da framework “GameUtil2D” (conforme já foi mostrado), e logo em seguida, copie todas as imagens presentes dentro da pasta “Capitulo 5” (que já acompanha este material) para dentro do nosso projeto, para a pasta “Content” . Feito isso realize aquele processo “Copiar para Diretório” para todas as imagens (“Sempre copiar”).
78
Luciano Alves da Silva Para começarmos digite a seguinte linha destacada em negrito na seção de declaração (importação) das bibliotecas do C#: : using Microsoft.Xna.Framework.Graphics; using Microsoft.Xna.Framework.Input; using Microsoft.Xna.Framework.Media; using gameutil2d.classes.basic;
Agora dentro da seção de declaração de atributos da classe vamos digitar as seguintes instruções em negrito abaixo : public class Game1 : Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Image aviao, nuvem, ceu_azul;
Agora dentro do método LoadContent vamos digitar o seguinte bloco de comandos destacados em negrito a seguir : protected override void LoadContent() { //Create a new SpriteBatch, which can be used to draw // textures. spriteBatch = new SpriteBatch(GraphicsDevice); GD.instance = GraphicsDevice; aviao = new Image(Content, "aviao", 0, 0, 90, 70); nuvem = new Image(Content, "nuvem", 250, 100, 90,70); ceu_azul = new Image(Content, "ceu_azul", 0, 0, 800, 480); }
79
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Agora vamos no método Draw para adicionarmos as seguintes linhas de comando: protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); ceu_azul.Draw(spriteBatch); nuvem.Draw(spriteBatch); aviao.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
Nas linhas de comando que adicionarmos acima, todas elas, desenham as imagens na tela do jogo. Agora, as linhas de comando acima foram adicionadas na seguinte sequencia: A primeira linha de comando que adicionarmos, desenha a imagem do céu azul na tela, até ai tudo bem. Na linha seguinte desenhamos a nuvem na tela, essa nuvem será desenhada “na frente” da imagem do céu azul. Por último, desenhamos a imagem do avião, e esse avião será desenhado na frente da imagem da nuvem e do céu azul (conforme já foi explicado no capítulo anterior, mas sendo reforçado neste capítulo).
80
Luciano Alves da Silva
Depois de escrever o código , vamos executar nossa aplicação e conferir os resultados:
Jogo em execução na tela
Por enquanto só conseguimos visualizarmos o nosso avião, mas, não podemos movimentá-lo pela tela ainda. Como havia falado, iremos movimentar os objetos via teclado (neste caso aqui, o avião). Vamos voltar na seção de declaração de atributos e lá vamos declarar a seguinte instrução, como segue:
81
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] public class Game1 : Game { GraphicsDeviceManager graphics; SpriteBatch spriteBatch; Image aviao, nuvem, ceu_azul; KeyboardState teclado; :
No comando destacado em negrito declaramos uma variável chamada teclado do tipo KeyboardState (que é uma classe que possui recursos que detecta estados do teclado. Por exemplo: verificar se uma tecla está pressionada ou solta) Agora dentro do método Update vamos digitar o seguinte bloco de comandos destacado em negrito abaixo: protected override void Update(GameTime gameTime) { // Allows the game to exit if (GamePad.GetState(PlayerIndex.One).Buttons.Back == ButtonState.Pressed) this.Exit(); // TODO: Add your update logic here teclado = Keyboard.GetState(); if (teclado.IsKeyDown(Keys.Right)) aviao.MoveByX(5); else if (teclado.IsKeyDown(Keys.Left)) aviao.MoveByX(-5); else if (teclado.IsKeyDown(Keys.Up)) aviao.MoveByY(-5);
82
Luciano Alves da Silva else if (teclado.IsKeyDown(Keys.Down)) aviao.MoveByY(5); base.Update(gameTime); }
Vamos analisar os comandos digitados em negrito. Na instrução : teclado = Keyboard.GetState();
A variável teclado recebe uma instância do método GetState (da classe Keyboard) que retorna todas teclas (pressionadas e não pressionadas) do teclado. Na próxima instrução : if (teclado.IsKeyDown(Keys.Right)) aviao.MoveByX(5);
Verifico se a tecla de direção para direita (representada por “Keys.Right”)
está
pressionada,
através
do
método
IsKeyDown. Caso verdadeiro, é executado o método MoveByX que é responsável por deslocar o nosso avião. Observe que o valor que passamos como parâmetro para o método foi 5, ou seja, nosso avião irá andar 5 pixels para a direita partindo da posição atual que ele se encontra.
83
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] A explicação acima é similar para as demais condições seguintes. Vamos executar a aplicação para conferir os resultados, conforme mostra a figura seguinte (não se esqueça de remover a instrução de “tela cheia” do código):
Movendo nosso avião pela tela
Se observarmos o jogo, nós conseguimos mover o avião pela tela, porém, a nuvem que adicionamos no jogo está imóvel. O ideal seria que essa nuvem se movimentasse, dando a sensação de que o avião está voando (em movimento).
84
Luciano Alves da Silva
Para colocarmos a nuvem em movimento, precisaremos adicionar mais algumas instruções. Para começar vamos declarar um atributo, conforme você pode conferir em seguida (na seção de declaração de atributos) : int largura_tela;
Agora dentro do método LoadContent vamos adicionar a seguinte instrução destacada em negrito abaixo: protected override void LoadContent() { nuvem = new Image(Content, "nuvem", 250, 100, 90, 70); ceu_azul = new Image(Content, "ceu_azul", 0, 0, 800, 480); //Retorna a largura da tela (que por padrão é //800) largura_tela = GraphicsDevice.Viewport.Width; }
Agora dentro do método Update vamos adicionar o seguinte comando destacado em negrito, como segue: protected override void Update(GameTime gameTime) { : else if (teclado.IsKeyDown(Keys.Down)) aviao.MoveByY(5); nuvem.MoveByX(-15); if (nuvem.GetX() < -nuvem.GetWidth()) nuvem.SetX(largura_tela); base.Update(gameTime); }
85
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Irei explicar cada linha de comando das instruções adicionadas acima. A linha: nuvem.MoveByX(-15);
Desloca a nuvem para a esquerda, de 15 em 15 pixels (lembre-se : valor positivo significa deslocamento pra direita, e valor negativo deslocamento para esquerda). A próxima instrução : if(nuvem.GetX() < -nuvem.GetWidth())
Verifica se a nuvem saiu for a da tela. Como interpretamos a avaliação feita pela condição acima ? Irei explicar para você. O método GetX (do objeto nuvem, do tipo Image) retorna a posição da coordenada X do objeto na tela, e o método GetWidth retorna a largura do objeto. Quando a posição X de qualquer objeto for menor que o valor negativo de sua largura, significa que o objeto não está visível na tela, ou seja, está fora dela (fora pelo lado esquerdo da tela). Quando isso acontece, é executada a seguinte instrução: nuvem.SetX(largura_tela);
Que reposiciona a nuvem para surgir a partir da direita da tela, dando a sensação que o avião está realmente voando. Execute novamente a aplicação e confira o resultado:
86
Luciano Alves da Silva
Nuvem em movimento Se observarmos o nosso jogo, o avião pode se deslocar perfeitamente pela tela, porém, se deixarmos o avião se mover constante (e unicamente) para uma direção, o mesmo sai da tela (independente se é para frente, pra trás, pra cima ou para baixo). Como solucionar esse problema ? É simples, basta limitarmos seu movimento de forma que o mesmo não saia da tela. Para realizarmos esse procedimento, primeiramente, vamos declarar o seguinte atributo em seguida (destacado em negrito):
87
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] int largura_tela; int altura_tela;
Agora dentro do método LoadContent vamos digitar a seguinte linha de comando destacada em negrito: protected override void LoadContent() { : largura_tela = GraphicsDevice.Viewport.Width; altura_tela = GraphicsDevice.Viewport.Height; }
Agora vamos dentro do método Update para digitarmos as seguintes linhas de código destacadas em negrito abaixo: protected override void Update(GameTime gameTime) { : teclado = Keyboard.GetState(); if (teclado.IsKeyDown(Keys.Right)) { aviao.MoveByX(5); if ((aviao.GetX() + aviao.GetWidth()) > largura_tela) aviao.SetX(largura_tela – aviao.GetWidth()); }
else if (teclado.IsKeyDown(Keys.Left))
88
Luciano Alves da Silva { aviao.MoveByX(-5); if (aviao.GetX() < 0) aviao.SetX(0); } else if (teclado.IsKeyDown(Keys.Up)) { aviao.MoveByY(-5); if (aviao.GetY() < 0) aviao.SetY(0); } else if (teclado.IsKeyDown(Keys.Down)) { aviao.MoveByY(5); if ((aviao.GetY() + aviao.GetHeight()) > altura_tela) aviao.SetY(altura_tela aviao.GetHeight()); } : }
Irei explicar agora a finalidade de cada instrução adicionada no código. A instrução:
if((aviao.GetX() largura_tela)
+
aviao.GetWidth())
>
Avalia se o avião está começando a sair da tela indo para frente (se a posição atual do avião na coordenada X somado
89
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] com a largura do mesmo for maior que a largura da tela. Isso é uma regra padrão). Caso a condição seja verdadeira, é executada seguinte instrução: aviao.SetX(largura_tela - aviao.GetWidth());
Que impede que o avião saia da tela, através do reajuste da posição dele na coordenada X, que será : largura da tela – largura do avião. Quando o avião anda para trás, é executada a seguinte avaliação condicional: if(aviao.GetX() < 0)
Que verifica se o avião está começando a sair da tela (se a posição X do objeto for menor que 0). Se a condição for verdadeira, será executada a seguinte instrução: aviao.SetX(0);
Que reajusta a posição do avião , pela coordenada X (definindo a coordenada X com o valor “0”). Quando o avião anda para cima, é executada a seguinte avaliação condicional: if(aviao.GetY() < 0)
Que verifica se o avião está começando a sair da tela (se a posição Y do objeto for menor que 0). Se a condição for verdadeira, será executada a seguinte instrução:
90
Luciano Alves da Silva
aviao.SetY(0);
Que reajusta a posição do avião , pela coordenada Y (definindo a coordenada Y com o valor “0”). Quando o avião está se movimentando para baixo, é executada a seguinte avaliação: if((aviao.GetY() + aviao.GetHeight()) > altura_tela)
Que verifica se o avião está começando a sair da tela (se a posição atual do avião na coordenada Y somado com a altura do mesmo for maior que a altura da tela. Isso é uma regra padrão). Caso a condição seja verdadeira, é executada a seguinte instrução: aviao.SetY(altura_tela - aviao.GetHeight());
Que impede que o avião saia da tela, através do reajuste da posição dele na coordenada Y, que será a altura da tela – a altura do avião. Executando nossa aplicação, teremos o seguinte resultado:
91
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Agora o avião não sai mais da tela
92
Luciano Alves da Silva
Capitulo 6 Trabalhando com animação de sprites
N
os capítulos anteriores aprendemos a visualizar imagens “estáticas” no jogo (pode ser qualquer elemento do jogo como uma árvore, um poste, um bloco e etc.). Agora, se eu quisesse que algum elemento do jogo apresenta-se alguma animação ? Neste capítulo vamos aprender como realizar essas animações usando sprites no jogo.
Na maioria dos jogos em 2D (talvez podemos dizer todos), alguns dos elementos apresentam algum tipo de animação (como o movimento de um personagem ou a ação de algum objeto). Agora a pergunta que faço é : como são realizadas essas animações no jogo ? Essas animações são realizadas utilizando o que nós chamamos de sprites. O que vem a ser uma sprite ? Sprites nada mais são do que um conjunto de imagens, onde cada imagem representa o movimento ou ação de um determinado elemento do jogo (como um personagem ou um objeto do jogo qualquer). Vamos ver abaixo um conjunto de imagens (sprites) de um personagem, onde cada imagem representa um movimento:
93
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Sprites de um personagem de um jogo (dando soco) Como funciona a animação de um personagem (ou objeto) durante o jogo ? Se observarmos as imagens acima, cada uma delas representa um movimento, e cada uma delas é exibida numa fatia de “tempo”, dando a sensação de movimento ou ação. Para trabalharmos com animação de sprites aqui no MONOGAME
faremos
uso
da
classe
chamada
AnimationSprites, destinada somente para esse tipo de tarefa (presente dentro do pacote “gameutil2d.classes.basic” da nossa biblioteca).
Para começarmos vamos criar um novo projeto no MONOGAME chamado “Animacao_de_Sprites”. Em seguida, copie todos os arquivos da biblioteca “GameUtil2D” para
94
Luciano Alves da Silva dentro do seu projeto e , por último, copie todas as imagens presentes dentro da pasta “Capitulo 6” (que acompanha este material) para dentro da pasta ”Content”. Não se esqueça de realizar o processo de “Copiar para Diretório” para todos os arquivos inseridos em “Content”. Agora dentro da seção de declaração de bibliotecas, digite a seguinte linha de comando abaixo: using gameutil2d.classes.basic;
Agora dentro da classe Game1 , na seção de declaração de atributos, vamos digitar a seguinte instrução abaixo: AnimationSprites naruto;
Agora dentro do método LoadContent vamos digitar o seguinte bloco de comandos destacados em negrito abaixo: protected override void LoadContent() { // Create a new SpriteBatch, which can be used to // draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); GD.instance = GraphicsDevice; naruto = new AnimationSprites(Content, 0, 0, 124, 164); naruto.Add("naruto_parado_1"); naruto.Add("naruto_parado_2"); naruto.Add("naruto_parado_3"); naruto.Add("naruto_parado_4"); naruto.Start(6, true); }
95
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Irei explicar o código inserido no método acima. A linha de comando: naruto = new AnimationSprites(Content, 0, 0, 124, 164);
Carrega a instância do objeto naruto do tipo AnimationSprites. No primeiro argumento da classe, sempre passamos o valor “Content”. No segundo e terceiro parâmetro, passamos respectivamente a coordenada X e Y do objeto na tela. Já os dois últimos parâmetros representam , respectivamente , a largura e a altura do objeto (124 para largura e 164 para altura). Nas linhas de comando seguinte: : naruto.Add(“naruto_parado_1”); naruto.Add(“naruto_parado_2”); naruto.Add(“naruto_parado_3”); naruto.Add(“naruto_parado_4”); :
Adicionamos as imagens (sprites) dentro do objeto, para que possamos ter uma animação do personagem, através do método Add. Em seguida, vem a seguinte instrução: naruto.Start(6, true);
Que tem a finalidade de “iniciar” a animação, através do método Start. Esse método possui dois parâmetros : O primeiro parâmetro é responsável por definir, em frames, o
96
Luciano Alves da Silva intervalo da troca de imagens, e o segundo definimos se a animação vai ficar “em loop” (caso true) ou não (caso false). Agora no método Draw vamos adicionar a seguinte instrução destacada: protected override void Draw(GameTime gameTime) { GraphicsDevice.Clear(Color.CornflowerBlue); // TODO: Add your drawing code here spriteBatch.Begin(); naruto.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
Antes de executarmos, retire a seguinte instrução dentro do método construtor da classe : graphics.IsFullScreen = false;
Depois de digitar o código solicitado, execute o nosso jogo e confira o resultado, como demonstra a figura seguinte:
97
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Animação do personagem em execução Em uma animação de sprites também podemos aplicar o efeito de “flip” (inversão) de uma imagem, na horizontal (como já havíamos visto com imagens estáticas). Para invertermos uma imagem na horizontal, basta adicionar um parâmetro no método Draw do objeto, o valor true. Vamos voltar para o método Draw da classe Game1 para substituirmos a linha abaixo: naruto.Draw(spriteBatch);
Por essa: naruto.Draw(spriteBatch,true);
98
Luciano Alves da Silva
Depois de realizar a alteração no código execute novamente o jogo , conforme demonstra o resultado mostrado abaixo .
Animação invertida na horitontal
Mais um exemplo de animação de sprites Vamos realizar agora mais uma pratica de animação de sprites no MONOGAME usando a classe AnimationSprites. Para essa pratica vamos descompactar um projeto já feito (que já acompanha este material), que é o arquivo “AnimacaoSprites_GundamWing.zip” (presente dentro da pasta “Capitulo 6”).
99
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Após descompactar o arquivo AnimacaoSprites_GundamWing.zip” vamos abrir o projeto , que se encontra dentro do diretório “AnimacaoSprites_GundamWing”, conforme mostra a figura seguinte:
Projeto descompactado Depois de abrir o nosso projeto execute-o, e confira o resultado conforme demonstra a figura seguinte:
100
Luciano Alves da Silva
Jogo em execução
Esse é um exemplo baseado no jogo “Gundam Wing – Endless Duel”, um dos grandes sucessos da plataforma “Super Nitendo”. A intenção deste exemplo é trocarmos as posições dos personagens do jogo. Para isso, vamos na classe Game1 e, em seguida, vamos realizar as seguintes modificações citadas a seguir: Dentro do método LoadContent vamos substituir as seguintes linhas de código destacadas em negrito abaixo:
101
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
protected override void LoadContent() { : //Carrega a animação do primeiro personagem wing_gundam = new AnimationSprites(Content, 100, 130, 200, 250); wing_gundam.Add("wing_gundam_parado_1"); wing_gundam.Add("wing_gundam_parado_2"); : //Carrega a animação do segundo personagem heavy_arms = new AnimationSprites(Content, 450, 120, 197, 263); heavy_arms.Add("heavy_arms_parado_1"); heavy_arms.Add("heavy_arms_parado_2"); : }
Pelas seguintes destacadas em negrito em seguida : protected override void LoadContent() { : //Carrega a animação do primeiro personagem wing_gundam = new AnimationSprites(Content, 450, 130, 200, 250); wing_gundam.Add("wing_gundam_parado_1"); wing_gundam.Add("wing_gundam_parado_2"); : //Carrega a animação do segundo personagem heavy_arms = new AnimationSprites(Content, 100, 120, 197, 263); heavy_arms.Add("heavy_arms_parado_1"); heavy_arms.Add("heavy_arms_parado_2"); }
102
Luciano Alves da Silva Agora dentro do método Draw vamos substituir as seguintes linhas de código destacadas em negrito abaixo:
protected override void Draw(GameTime gameTime) { : wing_gundam.Draw(spriteBatch); heavy_arms.Draw(spriteBatch,true); }
Pelas seguintes linhas de código destacadas em negrito abaixo:
protected override void Draw(GameTime gameTime) { : wing_gundam.Draw(spriteBatch,true); heavy_arms.Draw(spriteBatch); }
Depois de realizada as modificações execute novamente o nosso jogo, e confira o resultado que é mostrado na figura a seguir:
103
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Jogo em execução – Imagens trocadas
Regras para a criação de sprites Quando vamos criar as sprites (animações) de um determinado elemento de um jogo, normalmente, cada imagem que irá representar uma ação desse elemento deve ter o mesmo tamanho (padronizado para cada elemento do jogo), e quando salvas, deverão estar nomeadas de forma que fique fácil a organização das imagens (como por exemplo : personagem_andando_1.png , personagem_andando2.png e etc.).
104
Luciano Alves da Silva
Capitulo 7 Detectando colisões entre objetos no jogo
U
ma das técnicas mais importantes, que não se pode faltar em um jogo, é a detecção de colisões entre elementos . Neste capítulo, iremos aprender a detectar se dois objetos (ou mais) se colidem um com o outro no jogo, através dos recursos oferecidos neste material. Primeiramente vamos criar um novo projeto MONOGAME chamado “Colisoes_entre_Objetos”.
no
Depois de criarmos o projeto, copie todos os arquivos da framework “GameUtil2D” para dentro do projeto, e por ultimo copie todas as imagens (presentes dentro da pasta “Capitulo 7”) para dentro projeto na pasta “Content”, não esquecendo de realizar o processo de “Copiar para Diretório”. Vamos dentro da classe Game1 na seção de declaração de bibliotecas para digitarmos o seguinte código abaixo: using gameutil2d.classes.basic;
105
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Dentro da seção de declaração de atributos da classe, vamos realizar as declarações abaixo, como segue: AnimationSprites personagem; Image cenario; Image obstaculo,obstaculo2; KeyboardState teclado;
Agora dentro do método LoadContent vamos adicionar as seguintes instruções: protected override void LoadContent() { // Create a new SpriteBatch, which can be used to // draw textures. spriteBatch = new SpriteBatch(GraphicsDevice); // TODO: use this.Content to load your game content // here GD.instance = GraphicsDevice; personagem = new AnimationSprites(Content, (400 – 24), 305, 48, 50); personagem.Add("monstro_andando_1"); personagem.Add("monstro_andando_2"); personagem.Start(10, true); cenario = new Image(Content, "cenario", 0, 0, 800, 480); obstaculo = new Image(Content, "obstaculo", 80, 253, 68, 120); obstaculo2 = new Image(Content, "obstaculo", 630, 253, 68, 120); }
106
Luciano Alves da Silva
Agora dentro do método Update vamos adicionar as seguintes instruções destacadas em negrito: protected override void Update(GameTime gameTime) {
: // TODO: Add your update logic here teclado = Keyboard.GetState(); if (teclado.IsKeyDown(Keys.Right)) personagem.MoveByX(5); else if (teclado.IsKeyDown(Keys.Left)) personagem.MoveByX(-5); base.Update(gameTime); }
Agora dentro do método Draw vamos adicionar as seguintes instruções destacadas em negrito: protected override void Draw(GameTime gameTime) {
: // TODO: Add your drawing code here spriteBatch.Begin(); cenario.Draw(spriteBatch); personagem.Draw(spriteBatch); obstaculo.Draw(spriteBatch); obstaculo2.Draw(spriteBatch); spriteBatch.End(); base.Draw(gameTime); }
107
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Depois de digitar os códigos solicitados, execute a aplicação e confira o resultado:
Jogo em execução Se observarmos o jogo acima nosso personagem pode se movimentar de um lado para o outro, porém, o nosso personagem não pode ultrapassar os obstáculos (que são os elevadores). A ideia seria desenvolver um código que irá detectar a colisão do personagem com os obstáculos, que no caso são os elevadores.
108
Luciano Alves da Silva Para adicionarmos o código de colisão vamos no método Update para adicionarmos as seguinte instruções, destacados em negrito abaixo: protected override void Update(GameTime gameTime) {
: if (teclado.IsKeyDown(Keys.Right)) { personagem.MoveByX(5); //Colidiu com o obstáculo da direita //("obstaculo2") if (Collision.Check(personagem, obstaculo2)) personagem.MoveByX(-5); } else if (teclado.IsKeyDown(Keys.Left)) { personagem.MoveByX(-5); //Colidiu com o obstáculo da esquerda //("obstaculo") if (Collision.Check(personagem, obstaculo)) personagem.MoveByX(5); } base.Update(gameTime); }
Irei explicar agora o código que avalia a colisão do personagem com as barras horizontais e verticais. A expressão abaixo: if (teclado.IsKeyDown(Keys.Right))
109
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA] Verifica se a tecla seta para direita foi pressionada através do método IsKeyDown (com o argumento “Keys.Right”). Se a condição for verdadeira, é executado a instrução dentro da condição : personagem.MoveByX(5);
Em uma determinada circustância, poderá haver um determinado momento em que o personagem poderá se colidir com o obstáculo da direita (o objeto obstaculo2). agora, como avaliar se houve a colisão ? Para verificar se houve uma colisão entre dois objetos usamos o método Check da classe Collision, como podemos ver na instrução abaixo: if(Collision.Check(personagem, obstaculo2))
Se ocorrer uma colisão, nosso personagem irá voltar um passo anterior (se ele andou 5 pixels para direita e nesse movimento ele colidiu com o obstáculo, ele voltará um passo anterior), conforme você confere em seguida: personagem.MoveByX(-5);
A explicação das condições seguintes é “similar” ao que foi explicado agora. Vamos executar agora a nossa demonstração e conferir os resultados.
110
Luciano Alves da Silva
Jogo em execução – Personagem colide com o elevador Como pudemos observar acima, a colisão é uma das técnicas de desenvolvimento de jogos mais importantes. Com essa técnica conseguimos muitas coisas (como verificar se o personagem está pisando em algum bloco, se um tiro atingiu o inimigo e etc.).
111
Desenvolvendo Jogos com o Framework MONOGAME - Guia para Desenvolvedores [VERSÃO DE AMOSTRA]
Considerações Finais
Neste livro aprendemos SOMENTE AS NOÇÕES BÁSICAS de desenvolvimento
de
jogos
através
do
framework
MONOGAME. Vimos um pouco sobre fundamentos de desenvolvimento de jogos e aprendemos a instalar o MONOGAME
(juntamente
Conhecemos
também
um
com
o
pouco
Xamarim da
Studio).
biblioteca
de
desenvolvimento de jogos para MONOGAME chamado GameUtil2D (que eu mesmo desenvolvi) que pode ser utilizado junto com o projeto e como construir algumas demonstrações de jogo utilizando ela. Para o aprendizado COMPLETO desta obra, adquira a VERSÃO
COMPLETA
do
livro
no
http://lucianodev.com
Espero que esse material lhe tenha sido útil. Um forte abraço!
112
meu
site
: