Jogo 3D em Blender
Patrick do Carmo Guedes nº26023
Vitor Manuel Albuquerque Mendes nº24127
Projeto realizado sob a orientação de:
Professor Leonel Deusdado
Engenharia Informática
Junho de 2015
iii
Jogo 3D em Blender
Relatório da UC de Projeto
Licenciatura em Engenharia Informática
Escola Superior de Tecnologia e de Gestão
Patrick Guedes
Vitor Mendes
v
Certifico que li este relatório e que na minha opinião, é adequado no seu conteúdo e forma como demonstrador do trabalho desenvolvido no âmbito da UC de Projeto.
___________________________________________
Professor Leonel Deusdado - Orientador
Certifico que li este relatório e que na minha opinião, é adequado no seu conteúdo e forma como demonstrador do trabalho desenvolvido no âmbito da UC de Projeto.
___________________________________________
Arguente
vii
Agradecimentos
Queremos agradecer ao nosso orientador, Professor Leonel Deusdado, pela sua disponibilidade
orientação e apoio durante o desenvolvimento deste projeto que foi fundamental, pois sempre
nos motivou a não desistir mesmo quando as coisas pareciam correr menos bem.
Queremos agradecer a todos os nossos professores e a todos os colegas com que partilhamos
estes anos como alunos do IPB e como se costuma dizer: “No dia em que se chega a esta cidade,
chora-se porque se quer ir embora, mas depois chora-se porque não a queremos abandonar”.
Gostaríamos também de agradecer a toda a comunidade do fórum blenderartists e ao youtuber
arsenal rsl pelo esclarecimento de dúvidas e ajuda prestada.
Eu, Patrick Guedes, gostaria de agradecer aos meus pais, mas em especial á minha mãe porque
se estou a terminar o curso e este projeto, é graças a ela que sempre acreditou em mim, e me
apoiou em todas as decisões boas ou más que tomei ao longo destes anos.
Eu, Vitor Mendes, queria agradecer á minha família, em especial aos meus pais, por todo esforço
que fizeram e pelo apoio dado durante a realização do curso.
ix
Resumo
O Mundo dos Jogos é atualmente uma das indústrias de entretenimento que mais lucro produz
á escala global e nomeadamente uma das que mais evolui. Se a tecnologia se desenvolve, os
jogos acompanham esse desenvolvimento, tornando-os uma consequência positiva.
As empresas de desenvolvimento de jogos têm apostado em diversas plataformas
nomeadamente consolas, computadores, dispositivos móveis e mais recentemente nas redes
sociais.
O desenvolvimento de jogos em 3D oferece uma perspetiva mais global e apelativa, pelo que
nesta unidade curricular de projeto iremos desenvolver um jogo 3D para computador contruído
no Motor de Jogos do software Blender, que incorpora a linguagem de programação Python para
scripts.
O jogo que irá ser desenvolvido terá como objetivo principal mover sólidos geométricos para a
obtenção de cores que se encontram em uma ou mais plataformas de jogo. Poderá ser jogado
por qualquer pessoa de qualquer faixa etária.
Palavras-chave: Jogos, 3D, Motor de Jogos, Blender, Python
xi
Abstract
The World Games is currently one of the entertainment industry that produces more profit on a
global scale and in particular one of the fastest evolving. The technology develops then
everything evolves and games are no exception.
Companies developing games have scheduled games for different platforms including consoles,
computers, mobile devices, and more recently on social networks.
The 3D development offers a more global perspective and appealing in our opinion, so in this
project course we will develop a 3D computer game made in Blender software Games Engine,
which incorporates the Python programming language for scripting.
The game will be developed will be aimed move geometric solids to obtain colors which are one
or more game platforms. It can be played by anyone of any age group.
Keywords: Games, 3D Games Engine, Blender, Python
xiii
Conteúdos
1 Introdução ...............................................................................................................................1
1.1 Contextualização ...............................................................................................................1 1.2 Objetivos ...........................................................................................................................2 1.3 Motivação .........................................................................................................................2 1.4 Organização do relatório ..................................................................................................2
2 Estado da Arte .........................................................................................................................3
2.1 Software utilizado .............................................................................................................3 2.1.1 Blender .......................................................................................................................3 2.1.2 Game Engine ..............................................................................................................4 2.1.3 Layout do Game Engine .............................................................................................4 2.1.4 Python aplicado ao Blender .......................................................................................6
2.2 Casos de Estudo ................................................................................................................6 3 Planeamento e Desenho .......................................................................................................11
3.1 Nível 0 .............................................................................................................................11 3.1.1 Elementos presentes no nível .................................................................................11 3.1.2 Regras/Procedimentos para completar o nível .......................................................12
3.2 Nível 1 .............................................................................................................................12 3.2.1 Elementos presentes no nível 1 ..............................................................................13 3.2.2 Regras/Procedimentos para completar o nível .......................................................13
3.3 Nível 2 .............................................................................................................................14 3.3.1 Elementos presentes no nível 2 ..............................................................................15 3.3.2 Regras/Procedimentos para completar o nível .......................................................15
4 Implementação ......................................................................................................................17
4.1 Menus .............................................................................................................................17 4.2 Implementação do Nível 0 ..............................................................................................20 4.3 Implementação do Nível 1 ..............................................................................................22 4.4 Implementação do Nível 2 ..............................................................................................26
4.4.1 1ª Plataforma (Vento) ..............................................................................................26 4.4.2 2ª Plataforma (Fogo) ...............................................................................................28 4.4.3 3ª Plataforma (Perseguição e Universo)..................................................................31
4.5 Plataforma Mobile Android ............................................................................................35 5 Conclusões .............................................................................................................................39
5.1 Trabalho Futuro ..............................................................................................................39 Referências Bibliográficas ..............................................................................................................41
xv
Lista de Figuras
Figura 2.1: Layout e numeração dos painéis do Motor de Jogo .....................................................5 Figura 2.2: Controlador Python. ......................................................................................................6 Figura 2.3: Script Python..................................................................................................................6 Figura 2.4- Yo Frankie! .....................................................................................................................7 Figura 2.5: Color Cube .....................................................................................................................7 Figura 2.6: Cube Invasion ................................................................................................................8 Figura 2.7:Fun Karter Racer .............................................................................................................8 Figura 2.8: Orbito .............................................................................................................................9 Figura 2.9: I Will Escape ...................................................................................................................9 Figura 3.1: Esboço feito no papel sobre o possível cenário do Nível 0 .........................................11 Figura 3.2 - Esboço feito no papel da ilustração no Nível 1 ..........................................................13 Figura 3.3 - Esboço feito no papel da ilustração no Nível 2_Parte1 ..............................................14 Figura 3.4 - Esboço feito no papel da ilustração no Nível 2_Parte2 ..............................................14 Figura 4.1 – Menu de Instruções ...................................................................................................17 Figura 4.2 – Menu Inicial ...............................................................................................................17 Figura 4.3 – Carregamento de Nível ..............................................................................................18 Figura 4.4 – Menu de Pausa ..........................................................................................................18 Figura 4.5 – Lógica da Barra de Load .............................................................................................19 Figura 4.6 – Menu de Game Over ..................................................................................................19 Figura 4.7 – Menu de passagem de Nível ......................................................................................19 Figura 4.8 – Início do Nível 0..........................................................................................................20 Figura 4.9 – Nível 0 com cor vermelha obtida ...............................................................................20 Figura 4.10 – Lógica do cubo do Nível 0 ........................................................................................21 Figura 4.11 – Início do Nível 1 .......................................................................................................22 Figura 4.12 – Troca de sólido geométrico .....................................................................................23 Figura 4.13 – Esfera pintada ..........................................................................................................23 Figura 4.14 – Lógica da Câmara de 3ª Pessoa para o cubo ...........................................................24 Figura 4.15 – Câmara de 3º Pessoa para o cubo ...........................................................................24 Figura 4.16 – Sequência de cores completa ..................................................................................25 Figura 4.17 – Lógica para ganhar ...................................................................................................25 Figura 4.18 – Início do nível 2 (Vento) ...........................................................................................27 Figura 4.19 – Lógica da hélice ........................................................................................................27 Figura 4.20 – Lógica da torre .........................................................................................................27 Figura 4.21 – Sequência de cores do cubo completa ....................................................................28 Figura 4.22 – Lógica do cubo do nível 2 ........................................................................................28 Figura 4.23 – 2ª Plataforma (Fogo) ................................................................................................29 Figura 4.24 – Lógica do fogo ..........................................................................................................29 Figura 4.25 – Câmara 3ª pessoa ....................................................................................................30 Figura 4.26 – Lógica da esfera de perder vidas .............................................................................30 Figura 4.27 – Teletransporte .........................................................................................................31 Figura 4.28 – Última plataforma na câmara da esfera ..................................................................32 Figura 4.29 – Última plataforma (Perseguição e Universo) ..........................................................32 Figura 4.30 – Estrela ......................................................................................................................32 Figura 4.31 – Lógica da plataforma ...............................................................................................33 Figura 4.32 – Perseguição ..............................................................................................................33 Figura 4.33 – Finalização do nível e do jogo ..................................................................................34
xvi
Figura 4.34 – OgreKit .....................................................................................................................36 Figura 4.35 – Gamekit ....................................................................................................................36 Figura 4.36 – Finalizar projeto .......................................................................................................36 Figura 4.37 – ScreenShot Android ..................................................................................................37
xvii
Lista de Abreviaturas
BGE – Blender Game Engine
3D – Três Dimensões
GLSL – OpenGL Shading Language
“Chegar com novas ideias e converte-las em produtos reais foi sempre tão natural como respirar.”
Ralph Baer “Pai” dos vídeo jogos
1
Capítulo 1
1 Introdução
Nesta unidade curricular de projeto final de curso pretende-se implementar um jogo 3D,
originalmente para desktop. As etapas de implementação do jogo estão pendentes da definição
das regras, tipo de interface, tipo de jogo, ambiente/condições de jogabilidade.
Para o seu desenvolvimento ir-se-á recorrer ao Motor de Jogos do
Blender(blender.org(GameEngine)) que proporciona condições de movimentação, interação,
gravidade, deteção de colisões, trabalho de luz, entre outros.
1.1 Contextualização
O Mercado de jogos atingiu no ano 2013 um lucro no valor de 76 mil milhões de euros e cresce
a cada ano cerca de 9%,revelando assim que é uma indústria em constante expansão, mas
contudo controverso, pois há quem prefira os jogos de elevado nível gráfico e os que por outro
lado que pensam que já não se produzem jogos como alguns feitos antigamente(Cura 2015).
A nível interno o mercado português nos últimos anos registou um crescimento brutal desde o
cimentar dos casos de sucesso, como a Biodroid, às startups que lançam novos projetos de
potencial mundial, casos da Bica Studios ou Artbit Studios, ou o desenvolvimento com uma forte
identidade nacional, caso da Nerdmonkeys. Mas há também novos projetos ambiciosos que vão
desde Massive Multiplayer Online RPGs, como o Minimon3D, ou jogos que exploram áreas que
vão além dos ecrãs normais, como o projeto Cosmonaut da We Came From Mars que usa Oculus
Rift e Kinect(Caçador 2014).
Ou seja, tudo isto são boas sensações para os programadores visto que desde 2010 foram feitos
mais e melhores jogos do que na ultima década.
O jogo que se pretende desenvolver, quem sabe puder contribuir para ajudar o mercado interno
tem como âmbito entrar numa linha de dificuldade e divertimento independente do realismo
estabelecido, e acima de tudo obrigar o utilizador sentir-se desafiado.
2
1.2 Objetivos
Este projeto tem como principal objetivo a criação de um jogo 3D desenvolvido no motor de
Jogos Blender e aplicação da linguagem de programação Python.
Pretende-se também aplicar algum conhecimento adquirido anteriormente noutra unidade
curricular, nomeadamente Computação Gráfica e complementar com pesquisa para o
desenvolvimento do mesmo.
1.3 Motivação
Qualquer programador que se designe como tal, com certeza que aprecia jogos qualquer que
seja a plataforma ou género. Mas, melhor do que apreciar e jogar, é conseguir desenvolver.
Porque desenvolver um jogo é considerado também uma arte, pois tem-se pela frente o trabalho
de definir, moldar, construir, programar algo que no fim se consegue “sentir” o resultado prático
e que acima de tudo irá divertir pessoas libertando-as da rotina.
1.4 Organização do relatório
Para melhor orientação, o relatório está dividido em capítulos.
No primeiro é feita uma primeira introdução a este projeto, feita a sua contextualização no
mundo dos jogos atual, definição dos objetivos ao quais nos propusemos e motivação para a
realização deste projeto.
No segundo capítulo é elaborado o estado da arte, em que estudamos e analisamos alguns outros
jogos desenvolvidos no motor de jogos do Blender, e feita a introdução à tecnologia utilizada
para o desenvolvimento (Blender, Motor de Jogos do Blender, Linguagem de Programação
Python).
No terceiro capítulo de Planeamento e Desenho pretende-se começar a fundamentar o jogo,
fazendo esboços, explicando os elementos e lógica existentes.
No quarto capítulo de Implementação é explicado tudo o que foi feito para o desenvolvimento
do projeto consoante o planeamento feito.
No quinto capítulo ir-se-á concluir através de uma retrospetiva e análise pessoal do trabalho
realizado e apresentar ideias futuras para o jogo.
3
Capítulo 2
2 Estado da Arte
2.1 Software utilizado
2.1.1 Blender
O Blender, também conhecido por Blender3D, é um programa open source desenvolvido pela
Blender Foundation (Wikipédia(Foundation) 2015) para modelação, animação, textualização,
rendering, edição de vídeo e criação de aplicações interativas em 3D, como por exemplo jogos.
O seu lançamento foi em 1998 mas apenas 4 anos depois, em 2002 a empresa distribuidora do
programa acabaria por fechar devido a problemas financeiros. Nesse mesmo ano um co-
fundador do Blender, Ton Roosendaal (Wikipédia(Ton_Roosendaal) 2013) fundou a Blender
Foundation e alguns meses depois iniciou-se uma campanha para angariar €100.000 para os
investidores do programa concordarem em tornar o programa como open source. Em outubro
de 2002 foi lançada a versão livre do programa que atualmente ainda é desenvolvido pela Blender
Foundation.
O programa está disponível para diversos sistemas operativos, tendo ferramentas similares a
programas privados. Tanto o Blender como o seu motor de jogo suportam phyton como
linguagem de script(Wikipédia(Blender) 2015).
Desde o seu lançamento o Blender conta com alguns projetos de grande sucesso, como jogos e
animações. O seu primeiro grande projeto profissional foi o Homem-Aranha 2 em 2004, onde
foram criadas animações para fazer o esboço das cenas do filme.
Em 2008 a Blender Foundation e uma empresa por esta controlada, a Blender Institute (Wikipédia
2015), criaram o jogo Yo Frankie! (Wikipédia(YoFrankie) 2015), que é baseado na animação Big
Buck Bunny que foi produzida nesse mesmo ano. O jogo foi inicialmente conhecido como projeto
Apricot em que o jogador controla o Frankie, um esquilo. As personagens e cenários são
construídos no Blender Game Engine e o rendering em tempo-real foi feito no motor gráfico
Crystal Space (Wikipédia(Cristal) 2015).
4
2.1.2 Game Engine
O Blender Game Engine, também conhecido como BGE é o motor de jogo do Blender. O BGE usa
OpenGL para gráficos, OpenAL para som 3D, Bullet para física e deteção de colisão, e Python para
scripts. O uso do motor de jogo do Blender pode servir para diversas funcionalidades, desde
criação de jogos, apresentações, realidade virtual, auxílio em animação (usando a física para dar
movimentos mais reais aos objetos)(blender.org(GameEngine)).
A principal diferença entre o Motor de Jogo e o Blender em Modo Normal resume-se a:
Em Modo Normal podemos construir imagens ou animações em modo offline, e uma
vez feito render não podem ser modificadas.
No Motor de Jogo o processo de render é realizado continuamente em tempo real, e
incorpora também facilidades para o programador interagir com a cena durante o
processo de rendering.
O Motor de Jogos do Blender permite correr conteúdo no próprio programa mas é possível
também exportar o run-time para as diversas plataformas entre as quais, Windows, Linux,
MacOs(Arts 2009) e com suporte também para android. (blender.org)
Quando se pretende criar um jogo ou uma simulação usando o Motor de Jogo do Blender existem
quatro passos muito importantes:
Criar elementos visuais que podem ser alvo de rendering. Estes podem ser modelos 3D
ou imagens.
Permitir a interação dentro da cena usando blocos lógicos para um comportamento
personalizado, e determinar a maneira como a cena é invocada, usando os sensores
adequados como o teclado ou rato.
Criar uma ou mais câmaras para dar melhor perspetiva da melhor maneira para fazer
render da cena, e também modificar parâmetros de suporte do ambiente em que o jogo
vai ser exibido.
Correr o jogo, usando o player interno ou exportar para uma plataforma apropriada.
2.1.3 Layout do Game Engine
Para ajudar à conceção, construção, depuração, execução de um jogo o Blender incorpora uma
tela para esse efeito como se verifica na Figura 2.1. Alguns painéis existem no modo normal mas
5
também é adicionado um novo painel Logic Editor que é exclusivo do motor de jogo (BGE)
(Manual).
\
Figura 2.1: Layout e numeração dos painéis do Motor de Jogo
1) Game Logic
É selecionado na lista de Layouts de tela entre as várias aplicabilidades existentes.
Inclui já alguns painéis já familiares de informação, visualização em 3D, propriedades, e também
o painel Logic Editor especializado no motor de jogos.
2) Blender Game
Selecionamos esta opção no menu de motor de render.
Especifica os outputs que vão ser mostrados em tempo real pelo render do motor de jogo.
Ao selecionarmos esta opção, abre algumas outras opções de menu, entre as quais opções de
jogo e algumas propriedades entre as quais as de rendering.
3) Game
Este menu oferece várias opções para o funcionamento do Motor de Jogo. Esta opção está
disponível apenas quando o motor de render está selecionado no modo “Blender Game”.
4) Logic Editor
6
É neste painel onde a lógica, propriedades e estados estão configuradas para controlar o
comportamento dos objetos no jogo, com sensores (Ex: Teclado), controladores (Ex: Python) e
atuadores (Ex: Scene).
5) Propriedades
Painel de propriedades que se podem adicionar a qualquer objeto da cena. Boolean, Integer,
Float, String, Timer, são as propriedades disponíveis.
2.1.4 Python aplicado ao Blender
Python é uma linguagem de programação que é usada pelo Blender com o fim de correr scripts,
que podem ser utilizados para estender a funcionalidade do Blender sem ter que alterar as
versões binárias compiladas disponíveis. As versões binárias correntes do Blender vêm com uma
versão embutida e apropriada das bibliotecas do Python para ser usada.
Resumindo podemos criar um script recorrendo por exemplo a um controlador Python e criar os
nossos próprios scripts(blender.org(python)) como podemos observar nas Figura 2.2 e Figura 2.3.
Figura 2.2: Controlador Python.
Figura 2.3: Script Python.
.
2.2 Casos de Estudo
Atualmente vários jogos são criados em Blender, sendo a maioria projetos individuais
disponibilizados no fórum oficial http://blenderartists.org onde se pode encontrar projetos
completos ou ainda em desenvolvimento pela comunidade.
7
Yo Frankie!, o jogo criado pela Blender Institute em que o jogador controla um esquilo
num cenário divertido e com modo de 2 jogadores, como se pode verificar pela Figura
2.4.
Figura 2.4- Yo Frankie!
Color Cube(2010), um jogo de puzzle com 48 níveis com muita interatividade e lógica, que
é neste momento um jogo que está a ser comercializado.
Figura 2.5: Color Cube
8
Cube Invasion (2012), um projeto individual que desafia o jogador contra uma invasão de
cubos.
Figura 2.6: Cube Invasion
Fun Karter Racer (2015), uma corrida de carros em que pode obter armas e pode atingir
ou ser atingido pelos seus adversários.
Figura 2.7:Fun Karter Racer
9
Orbito (2011), jogo do estilo super-mario em que o jogador controla um macaco.
Figura 2.8: Orbito
Recentemente, a 22 de Dezembro de 2014 foi lançado o jogo I Will Escape. A primeira parte de
uma trilogia em que o jogador é um condenado que terá de escapar de uma prisão. Este é
primeiro jogo feito em Blender a estar à venda numa das maiores plataformas de jogos online, a
Steam(2014).
Figura 2.9: I Will Escape
11
Capítulo 3
3 Planeamento e Desenho
3.1 Nível 0
No seguimento de alguns casos de estudo de outros jogos e em conversação com o nosso
orientador reuniu-se consenso quanto ao tipo de jogo que seria desenvolvido. “Para quê criar
personagens que iriam custar muito tempo a construir, quando o Blender fornece por defeito
sólidos geométricos que podem funcionar como personagens.”
O objetivo do jogo que se realizou para ser criativo, consiste principalmente em usar sólidos
geométricos para apanhar cores espalhadas com uma certa lógica através de plataformas.
Assim sendo antes de passar á implementação propriamente dita, foi pensada a melhor maneira
de fazer um pré-visionamento do que se queria para o jogo. Nada melhor que o papel em branco
para exprimir toda a criatividade imaginada.
Para melhor perceber a ideia do ambiente de jogo, a Figura 3.1 representa um esboço pensado
para o Nível 0, que é nada mais do que um pequeno tutorial.
Figura 3.1: Esboço feito no papel sobre o possível cenário do Nível 0
3.1.1 Elementos presentes no nível
Por ser um pequeno nível para aprendizagem, não pode conter demasiada “informação” que
dificulte o entendimento da lógica do jogo.
12
Seguindo essa mesma ideia este primeiro nível apenas contém uma simples câmara bem
centralizada para a plataforma principal, em que o personagem é um cubo. Está presente desde
já uma sinalização das cores que é pretendido obter bem como a sequência que deve ser seguida.
São elementos muito simples, mas importantes no entendimento do que se pretende.
3.1.2 Regras/Procedimentos para completar o nível
Seguindo a lógica inventada, o objetivo para já como já foi referido é aprender. Para completar
o nível 0, basta movimentar o cubo primeiramente para a cor vermelha onde irá ser pintada a
cor no canto superior esquerdo. Depois de pintar a cor vermelha o cubo fica naturalmente
vermelho e assim de seguida, deve-se movimentar de novo o cubo para a cor azul. Assim se
completa a sequência de cores exigida e o nível termina de imediato. É importante referir que
quer as sequências e as cores que cada sólido deve pintar são nada mais que as formas de cada
sólido, isto é, um cubo está para um quadrado assim como uma esfera está para um círculo.
O modo de perder resume-se caso o cubo caia fora da plataforma, e o jogo reinicia
automaticamente.
3.2 Nível 1
O nível 1 de princípio foi pensado para ser o tutorial, mas foi notória alguma dificuldade para
entender o objetivo do jogo. Como ficou demonstrado aquando a nossa primeira apresentação
do projeto na primeira etapa de avaliação, assim foi decidido, melhorar alguns aspetos do
referido nível e desenvolver um muito mais básico para ser o nosso nível 0. Como se vai puder
observar na Figura 3.2, é possível começar a perceber a lógica do nível 1.
13
Figura 3.2 - Esboço feito no papel da ilustração no Nível 1
3.2.1 Elementos presentes no nível 1
A grande diferença que separa o nível 0 e nível 1 será o facto de começarem a ser usados mais
sólidos para apanhar cores. Mas isso será detalhado em pormenor no capítulo 4.
Assim sendo o nível 1 tem na sua constituição três câmaras em que uma delas se encontra numa
posição de completa visualização de todo o ambiente de jogo. Outras duas são melhorias em que
uma delas persegue o movimento do cubo, e outra segue a esfera ao estilo de jogo em 3ª Pessoa.
O mapa de jogo se assim quisermos chamar, são duas plataformas unidas por uma ponte em
subida que dificulta o movimento dos sólidos. Um temporizador no canto inferior direito é outra
nova implementação que conta no sentido descendente, para temporizar a conclusão das
sequências de cores presentes no tempo estabelecido inicialmente.
3.2.2 Regras/Procedimentos para completar o nível
O início do nível é começado desta vez com a esfera que terá que ser movida com o objetivo de
chegar á cor amarela, assim pintando a mesma e a primeira/única cor da sequência do sólido em
questão. Feito isto, é necessário trocar de sólido geométrico, e para isso terá que ser percorrido
o mapa com o intuito de encontrar o lugar correto e desconhecido pelo utilizador para trocar de
sólido, que foi devidamente sinalizado no esboço. Nesse momento a esfera sai do jogo e entra
um cubo. Assim resta ao cubo pintar de seguida a cor vermelha e a cor azul respeitando esta
14
ordem, pois outra ordem não é permitida pela sequência exigida inicialmente. A qualquer altura
do jogo é possível alternar de câmaras.
O modo de perder do nível 1 é cair no buraco (que possui uma força de atracão), cair fora da
plataforma, ou não completar o nível dentro do tempo estabelecido pelo cronómetro. Caso estas
condições aconteçam o nível reinicia automaticamente.
3.3 Nível 2
Neste item será falado sobre o último nível desenvolvido para o projeto. Trata-se de algo já mais
complexo que será detalhado ao longo deste relatório.
.
Figura 3.3 - Esboço feito no papel da ilustração no Nível 2_Parte1
Figura 3.4 - Esboço feito no papel da ilustração no Nível 2_Parte2
15
3.3.1 Elementos presentes no nível 2
Como é possível observar nas Figura 3.3 e Figura 3.4, o nível 2 é composto por duas partes.
Na Figura 3.3 existem vários elementos novos, entre os quais uma torre de vento, vasos de fogo,
que são os dois principais perigos. Existem naturalmente cores que são dos elementos principais,
vidas que convém não serem perdidas, um cubo, e uma esfera que entra em jogo na segunda
plataforma. Na segunda plataforma (assim que disponível) existe um teletransporte que conecta
a Figura 3.4 ao jogo, é a fase final do jogo em que existe uma plataforma redonda, com pedras e
outros obstáculos referenciados ao longo do capítulo.
Todas as plataformas e todos os sólidos geométricos possuem uma câmara própria para uma
melhor interação.
3.3.2 Regras/Procedimentos para completar o nível
O nível começa com um cubo em que terá como principais obstáculos alguns buracos na
plataforma, e uma torre de vento que caso se entre na sua proximidade, aplicará uma força que
o irá afastar. O objetivo passa entretanto por não ser apanhado no radar dessa torre e mover o
cubo para as cores que lhe pertencem, (no caso vermelho e amarelo por esta ordem). Feito o
primeiro objetivo de completar as cores, o cubo terá que saltar para a segunda plataforma, a qual
como já foi referido não se encontra parada, o que irá dificultar o objetivo, mas o que torna mais
fácil a mudança de sólido, pois a partir do momento em que o cubo colidir com a segunda
plataforma, irá desaparecer e entrar a esfera de imediato.
Se a primeira plataforma era relacionada com vento, a segunda é com fogo, em que a esfera não
deverá colidir, pois perderá uma vida por cada vez que o faça. O utilizador terá que conseguir
fazer face ao movimento da plataforma e mover o sólido para as cores que lhe correspondem,
assim desbloqueando um teletransporte que levará a esfera para a ultima fase do nível. Foi um
resumo da Figura 3.3.
Na Figura 3.4, segunda e última parte do nível, após o teletransporte a esfera “aterra” na
plataforma e terá como objetivo pintar a cor verde e ai sim completada a sequência de cores que
lhe corresponde, encontrar a maneira de trocar para cone.
16
Por cima de cada cor a uma altura significativa, estão rochas/pedras que estão programadas com
intervalos de tempo para cair. Caso isso aconteça, a cor que se pretendia pintar fica
automaticamente desativada o que obriga o utilizador a recomeçar o nível.
Entra então em jogo o último sólido, e por sua vez entra em cena uma espécie de pedra gigante
que faz perseguição ao cone. Com essa dificuldade acrescida, pretende-se que a serie de cores
seja cumprida e assim que a cor final (preto) for pintada, o cone é elevado até uma porta que lhe
permite sair do jogo e assim dar por encerrado o nível e finalizado o jogo.
Importante de referir que o modo de perder, pode ser por queda fora das plataformas, ou em
buracos que existam, entrar no radar da torre de vento será complicado sobreviver, colidir com
o fogo também não será uma boa opção. Ser apanhado pela pedra gigante irá fazer com que se
percam vidas também. Após a perda de três vidas o jogo entra num menu de game over o que
obriga a recomeçar. Caso se perca uma vida o jogo reinicia automaticamente podendo-se
continuar a jogar no ponto inicial de cada plataforma.
17
Capítulo 4
4 Implementação
4.1 Menus
Não existindo nenhuma API que pudesse facilitar a construção de um menu e o princípio de
desenvolvimento passou também pela mesma forma de desenvolver um nível, ou seja trabalhar
com modelação, lógica, propriedades, entre outras partes importantes.
Uma das partes mais importantes de qualquer jogo sem dúvida são os menus. Foi algo que foi
aprendido desde muito cedo no começo do desenvolvimento deste projeto. As Figura 4.1 e Figura
4.2, representam o menu inicial do jogo, e o menu principal de instruções respetivamente. Algo
que é notório é que por vezes o texto fica sem pontuação algo que nem sempre é fácil controlar.
O processo de criação de um menu consistente como o da Figura 4.2 é composto por vários
passos entre os quais iremos enumerar por tópicos:
Adicionar Câmara;
Plano para o fundo e texturizar;
Botão (plano mais texto) que para a sua criação obedece a algumas regras que
funcionaram em geral para todos os botões dos menus do jogo.
Figura 4.1 – Menu de Instruções Figura 4.2 – Menu Inicial
18
Texto para instruções ou botões (Edit Mode), (Alterar Texto), (Novo Material) (Converter
para Mesh)
Porque pensamos que fazer botões deve ser um pouco mais detalhado que o resto, a sua criação
engloba dois elementos principais: texto e um plano de fundo que irá servir de sensor, que neste
caso irá ter a lógica incorporada e que permite fazer a animação de um botão. Essa lógica é
composta por dois sensores de mouse que por sua vez ligados a dois controladores and e um
nand. Os atuadores são um scene para com o click do rato aceder a outra cena que pode ser a
Figura 4.1, um som de botão, e dois action que criam a animação da frame zero até á três e vice-
versa. A animação cria-se no sensor isto é abrindo o painel de timeline e na frame zero é inserido
o estado inicial e na frame três o estado final da animação pretendida. (Anexo 1).
O sensor e o texto para ficarem ligados é necessário criar um parentesco entre os dois objetos, o
que irá implicar que a lógica implementada no sensor atue também nas letras que é exatamente
o que se pretende visto que o sensor por fim ficando invisível não será visto pelo
utilizador.(ThaTimst3r)
A Figura 4.3 representa um carregamento com instruções próprias para cada nível criado. Por
sua vez a Figura 4.4 é um menu de pausa que permite a qualquer altura interromper o jogo.
O processo de construção de um carregamento de um nível, neste caso da Figura 4.3 é
importante referir que não carrega informação pois os níveis não contêm informação
propriamente dita. Este foi um menu pensado para uma pré-preparação antes de jogar, fornecer
Figura 4.3 – Carregamento de Nível Figura 4.4 – Menu de Pausa
19
algumas informações de ajuda. A barra de Load é o elemento que contém toda a lógica de ligação
que irá ser explicado se seguida.
A barra de carregamento do jogo para este projeto foi conseguida através dos seguintes passos:
Adicionar uma propriedade de tempo;
Dois sensores de always que sempre que a cena estiver ativa ativar,
Um controlador and e controlador python (Anexo 2);
Um atuador action e outro de scene.
Em conjunto criam uma animação que terminado o tempo treze segundos contados
decrescentemente o menu de load termina e começara o nível zero.
Os últimos dois menus mais importantes do jogo são como demonstram as Figura 4.6 e Figura 4.7, os menus de perder e ganhar o nível respetivamente.
Figura 4.5 – Lógica da Barra de Load
Figura 4.6 – Menu de Game Over Figura 4.7 – Menu de passagem de Nível
20
A lógica de construção prende-se com as dos menus anteriores descritos mas com a diferença
que ocorrem quando o utilizador estiver a jogar os níveis propriamente ditos. Não é possível
perder ou ganhar sem jogar. Os restantes menus podem ser analisados no Anexo 3.
4.2 Implementação do Nível 0
Como já foi referido no capítulo anterior o jogo é constituído por menus e níveis. Ao longo do
projeto foram conseguidos três níveis cada um deles seguindo a sua própria lógica, programação
e ideia.
Mas mais importante que desenvolver um jogo é torná-lo rapidamente apelativo no primeiro
contacto que qualquer jogador tenha pela primeira vez, e para isso contribuem os tutoriais que
servem essencialmente para aprender, mas também para atrair a atenção e curiosidade.
Nesse âmbito o primeiro nível de jogo, ao qual foi chamado de nível zero, resume-se a fazer um
primeiro contato com um dos objetivos que é movimentar um ou mais sólidos geométricos, cada
uma na sua vez, em uma ou mais plataformas a fim de completar sequências de cores. As Figura
4.8 e Figura 4.9 fazem este contato.
Na Figura 4.8 pode se observar que no canto superior esquerdo existem dois quadrados pintados
a vermelho e azul que representam a sequência de cores que o utilizador deve obedecer, e por
sua vez dois quadrados brancos que indicam quando a sequência se encontra completa.
Este primeiro nível e todos foram desenvolvidos em modo GSLS(opengl.org) que permite
melhores sombreamentos e grafismo foi construído com os seguintes objetos:
Figura 4.8 – Início do Nível 0 Figura 4.9 – Nível 0 com cor vermelha obtida
21
Um cubo que moldado e texturizado representa a plataforma de jogo;(rsl 2014)
Um cubo normal para ser o sólido principal que servirá para completar as cores.
Quatro planos moldados e texturizados que indicam a sequência e quando são obtidas
essas cores.
Desta forma a Figura 4.9 já representa um exemplo de quando uma cor é pintada no jogo. A sua
lógica de implementação obedece algumas regras que serão explicadas com a ajuda da Figura
4.10.
O processo para concretizar algo objetivo para um personagem de um jogo trata-se de algo que
não é completamente visível para quem começa a trabalhar com o motor de jogos do Blender. A
Figura 4.10 é um complemento muito importante para se perceber como se concretizam ações
com lógica para o nível zero.
Começando por partes, existem no cubo quatro sensores de keyboard que por sua vez são ligados
a quatro atuadores motion por intermédio de quatro controladores and, que basicamente
permitem “mexer” o cubo. Isto é, se inserirmos up arrow no sensor keyboard, 5 graus na rotação
e 0.09 na locação em X no atuador motion correspondente, o cubo irá andar em frente.
Para pintar uma cor(azul) neste caso destacado pela Figura 4.10 são usados dois sensores always
e collision que por sua vez são conectados por um controlador python azulN0.py(Anexo 4), a um
atuador scene. A script o que faz é quando a colisão com o objeto azul da plataforma suceder, o
Figura 4.10 – Lógica do cubo do Nível 0
22
cubo pintará de azul e a sequência terminará, e assim terminando o nível zero. O menu da Figura
4.7 é ativado.
Foi também adicionado um cubo que se encontra invisível com uma propriedade Game Over que
foi modelado para cobrir uma área restrita do nível. A sua função é em caso de o sólido colidir
com esse cubo o jogo recomeçará de imediato no ponto inicial.
A script para pintar a cor vermelha que também se encontra no Anexo 4 segue a lógica da script
azul mas com a programação correta de combinar propriedades para que a ordem seja
corretamente cumprida.
Isto é, existem na plataforma duas cores para pintar, nos quais o objeto vermelho tem uma
propriedade booleana verdadeira, e o objeto azul uma falsa. Caso o utilizador tente pintar
primeiro o cubo de azul não conseguirá porque para esse efeito a propriedade tem de ser
obrigatoriamente verdadeira, e para o conseguir terá que obter a cor vermelha que depois de
ser pintada passará a propriedade azul a verdadeira, possibilitando assim que a cor azul fique
disponível.
4.3 Implementação do Nível 1
Dando continuidade ao trabalho realizado até ao momento foi desenvolvido um primeiro nível
que vai exigir não muita, mas alguma perspicácia e atenção ao utilizador do que é pedido para
completar mais uma etapa. A Figura 4.11 serve para se puder fazer uma primeira análise.
Figura 4.11 – Início do Nível 1
23
Revelando já alguma complexidade a nível de construção, modelação e texturização de objetos
o nível um foi desenvolvido no modo multitexture, contudo numa fase mais tardia do projeto
percebeu-se que em modo GLSL o jogo se tornava mais estável quando se tentava jogar do
princípio ao fim percorrendo todos os menus e níveis.
O processo para a construção de um nível no BGE, passa essencialmente por três fases: O pensar
de como vai ser e para isso existe um planeamento e desenho, uma modelação passando do
papel à prática, e o mais fundamental a lógica que envolve. (Cookie 2011)
A modelação do nível um, englobou a modelação de vários objetos entre os quais um cubo, que
se transformou numa plataforma de jogo, para criar um ambiente de precipício modelou-se uma
esfera e aplicou-se uma textura, objetos para as sequências e cores, um plano para a porta de
saída. O temporizador é um texto que é convertido para algarismos, mas ao longo do relatório
dará para perceber melhor o que foi contruído.
A Figura 4.13 representa a primeira e única cor obtida pela esfera. Para esse efeito foi usada uma
script Python (excoramarela.py) que se encontra no Anexo 5 e o que faz é quando a colisão com
o objeto amarelo que se encontra na plataforma for positiva, a esfera adquire a sua cor e por sua
vez é pintada de amarelo o objeto no canto superior esquerdo indicando sucesso. O utilizador
ganha também uma bonificação de cinco segundos no temporizador. O código [1,1,0, True] faz
pinta o objeto de amarelo.
A Figura 4.12 é onde acontece um dos objetivos principais da lógica do jogo, ou seja a troca de
sólido geométrico, neste caso da esfera pelo cubo. A script(trocar.py) encontra-se também no
Figura 4.13 – Esfera pintada Figura 4.12 – Troca de sólido geométrico
24
Anexo 5 e é junção de duas scripts no mesmo ficheiro, no qual chama-mos a cada uma delas de
módulos.(switch e TrocarFig).
O módulo TrocaFig faz a colisão com um local da plataforma escolhido aleatoriamente acontecer
e a propriedade da esfera por verdadeira (passa a verdadeira quando pinta de amarelo), é
adicionado um cubo na cena que se encontra numa layer diferente, e a esfera desaparece.
Numa combinação de estados o módulo python TrocarFig envia também uma mensagem
através de um sensor que possibilita que assim que o cubo entre em cena, a câmara o comece a
seguir em modo de terceira pessoa ativando assim um segundo módulo switch que se encontra
também no Anexo 5. Este módulo tem a função fazer o seguimento do cubo em modo de
terceira pessoas. A lógica da Figura 4.14 resulta na Figura 4.15.(blenderArtists(Objects) 2015)
Recuando um pouco atrás foi também implementada uma força de atração para o buraco da
plataforma. Em modo invisível e abaixo do nível da plataforma na direção do buraco, encontra-
se um cubo que tem por objetivo afetar os sólidos com que se estiver a jogar. A script força.py
que se encontra no Anexo 5, é implementada na esfera, em que quando a distância para esse
cubo de atracão for menor que um determinado valor, será atraída para o buraco forçando o
utilizador a perder. Caso essa distância seja maior que o valor a atração deixa de funcionar.
O temporizador timer.py do Anexo 5 que se encontra no canto inferior esquerdo do ecrã foi
desenvolvido adicionando um texto que convertido origina algarismos. O seu funcionamento
começa a contar de ordem decrescente de 60 e quando chegar a 0, o nível recomeça do ponto
de partida seja qual for o sólido com que se esteja a jogar. A cor inicial do temporizador é azul
mas quando o tempo estiver nos 5 segundos finais a cor passa a vermelho para alertar o
Figura 4.15 – Câmara de 3º Pessoa para o cubo Figura 4.14 – Lógica da Câmara de 3ª Pessoa para o cubo
25
utilizador que o tempo para concluir o nível vai terminar.Foi também desenvolvido um método
para por exemplo, se o utilizador estiver a jogar na câmara principal, como existem outras
câmaras no jogo não serem visíveis apesar de existirem. (camera2.py Anexo 5). Existem mais
algumas scripts que foram implementadas para fazer este processo mas seguem a lógica da
referida anteriormente, no entanto foi necessário algum trabalho com propriedades para não
serem conflituosas.
Para concluir a implementação do nível um, a Figura 4.16 demonstra o objetivo completo.
Após a o utilizador conseguir pintar a última cor (neste caso o azul), é aberto um portão que
indica a saída. A lógica que possibilita este acontecimento é feita pela script portão.py que se
encontra no Anexo 6. Tem como função assim que a cor azul for pintada a propriedade
booleana do portão fica verdadeira que até aqui era falsa, ativando assim uma animação e um
som de abertura.
De seguida basta movimentar o cubo para a saída e assim se finaliza o nível um que é
concretizado pela Figura 4.17. Quando a colisão com a saída que tem a propriedade “ganhar”
for sucedida, um dos menus de sucesso de passagem de nível é mostrado ao utilizador.
Figura 4.16 – Sequência de cores completa
Figura 4.17 – Lógica para ganhar
26
O modo de perder para além do método enunciado no nível zero, pode ser também por não
finalizar o nível no tempo estabelecido ou ser atraído para o buraco da plataforma de jogo.
4.4 Implementação do Nível 2
Por ultimo, o nível dois que foi implementado neste projeto é uma amostra mais real da
capacidade do motor de jogos do Blender, embora seja uma ferramenta capaz de muitos mais.
Ao contrário dos outros níveis, este foi decidido para uma melhor perceção a sua divisão por
plataformas, onde serão explicadas as etapas mais cruciais no que à lógica e implementação diz
respeito.
Em relação ao planeamento e desenho o nível sofreu uma alteração pois continha uma
plataforma de água que mais tarde se concluir que não acrescentaria nada de objetivo ao jogo
pelo que não foi implementada.
É um nível que contém vários temas, objetivos, mais sólidos, novas funcionalidades, que assim
aumentaram o nosso conhecimento e aprendizagem sobre motor de jogos. Mais do que ser
benéfico para quem os produz é mais satisfatório saber que o utilizador final gosta e aprecia o
que foi feito.
4.4.1 1ª Plataforma (Vento)
Como demonstrado no capítulo anterior foram implementadas nas plataformas existentes um
ambiente diferente para cada uma delas. Neste caso foi decidido em que o tema principal seria
o vento.
A Figura 4.18 representa o início e a primeira plataforma do nível dois.
27
Passando pela modelação a que outros níveis também foram sujeitos as principais novidades
que se podem ver é a implementação de vidas para cada sólido que se encontram no canto
superior direito e uma torre com uma hélice geradora de vento.
A torre foi construída com dois objetos que estão ”ligados” por um parentesco selecionando os
dois objetos para os unir.
A Figura 4.19 é controlada por uma script helice.py que se encontra no Anexo 7 e tem um sensor
de radar que estabelece uma distância e um angulo para o cubo. Caso o cubo entre no radar da
hélice é aplicada uma forma de afastamento projetando o sólido.
O atuador motion tem como função fazer rodar a hélice enquanto o atuador sound simula um
som de vento, tornando o jogo o mais real possível. A Figura 4.20 faz com que a torre persiga o
cubo para todo o sítio que ele se movimente, mas sem se deslocar.
Evitando a hélice e tentando não perder vidas a Figura 4.21 demonstra um desbloqueio da
segunda plataforma de jogo, pois foi conseguido completar a sequência de cores do cubo.
Figura 4.19 – Lógica da hélice Figura 4.20 – Lógica da torre
Figura 4.18 – Início do nível 2 (Vento)
28
Para terminar a explicação da primeira plataforma a Figura 4.22 apresenta toda a lógica do cubo.
Resumindo, o cubo contém lógica para saltar, se movimentar, colisões para perder vidas e fazer
Game Over, trocar, pintar cores, e física Rigid Body com a opção actor que irá permitir atuadores
de outros objetos atuem no sólido. Para que o cubo mantenha um movimento original a massa
tem que ter um valor próximo de zero, radius igual a dez, e o form factor maior que um. A opção
collision bounds é também obrigatória caso contrário as rotações do cubo serão deficientes, isto
é, se o utilizador não completar uma rotação completa o cubo ficará esquinada e será difícil até
ter o cubo direito na plataforma de jogo.
4.4.2 2ª Plataforma (Fogo)
Como referido anteriormente cada plataforma tem um diferente tema, logo diferentes
obstáculos. O cubo após conseguir saltar para a segunda plataforma o que não se adivinha fácil
Figura 4.22 – Lógica do cubo do nível 2
Figura 4.21 – Sequência de cores do cubo completa
29
devido a esta não ser estática, transforma-se de imediato para a esfera que se pode ver na Figura
4.23.
Face á animação que atua nos eixos dos X da plataforma, o utilizador terá que ser perspicaz o
suficiente e fazer face á movimentação da placa em que a sua lógica se encontra no Anexo 8.
Da frame 0 até á 120 é reproduzida uma animação da “frente para trás” em que ativada por
sensor always, entra em loop o que permite estar sempre ativa. Foi escolhido este intervalo entre
as frames porque caso se aumentasse ou diminuísse o intervalo a animação ficaria muito rápida
ou demasiado lenta para o que era pretendido.
A script python destacada apenas tem como função igualar a propriedade booleana para falsa
que auxilia a esfera a saltar, visto que se for verdadeira o salto torna-se irreal e a esfera desloca-
se para o infinito se a tecla de espaço for constantemente pressionada.
Em relação ao fogo, foi criado graças a um emitter que é obtido através da instalação de um
addon chamado EasyEmit para o Blender. Adiciona-se quatro objetos e recorrendo às partículas
do addon cria-se dois objetos de fogo e de fumo.(blenderArtists 2013)
Figura 4.23 – 2ª Plataforma (Fogo)
Figura 4.24 – Lógica do fogo
30
A Figura 4.24 tem como função mais uma vez com a ajuda de um sensor de radar detetar a esfera
e quando a distancia for menor que 2.5 é enviado num atuador uma mensagem para a esfera
que a recebe como sensor. Se o radar for positivo a esfera fica de cor preta pois chegou perto do
fogo. Em caso de colisão total com o fogo a esfera perde uma vida que será explicada de seguida.
A Figura 4.25 demostra o que foi explicado antes, em que a esfera está de cor preta porque foi
apanhada no radar do fogo. No canto superior direito da imagem pode-se verificar que das três
esferas sobram apenas duas, pois a esfera ou colidiu com o fogo ou caiu fora da plataforma de
jogo. A Figura 4.26 que representa a lógica da esfera, destaca como foi implementada a perca de
vidas e do nível.
Os módulos Python destacados que se encontram no Anexo 9, correspondem à maneira de
perder cada vida individualmente, isto é verificando se as colisões que neles estão ligados são
positivas, nesse caso perde a vida correspondente. É também no módulo vidinha1 que a
mensagem do fogo é recebida assim possibilitando a esfera ficar preta, para além de perder a
primeira vida. Ao contrário dos outros níveis que perdendo o jogo recomeçava do início, foram
Figura 4.25 – Câmara 3ª pessoa
Figura 4.26 – Lógica da esfera de perder vidas
31
criados spawn_points que são objetos vazios que se encontram em pontos iniciais de cada
plataforma e quando uma vida é perdida, tomam a posição do sólido geométrico
correspondente. O “controlador de vidas” de cada sólido é uma propriedade inteira que é igual
a três à qual é decrementada um valor sempre que se perde uma vida. No módulo vidinha3 é
verificado se essa propriedade é igual a zero, e caso o seja a última vida é perdida, e o jogo
termina apresentando o menu de Game Over da Figura 4.6.
Caso o utilizador seja bem-sucedido, isto é, não perdendo todas as vidas e completando a
sequência de cores que se encontram disponíveis na plataforma desbloqueia um teletransporte
que se pode ver na Figura 4.27. A script responsável por permitir obter a cor laranja e
desbloquear o teletransporte é a script pintarLaranjaN2.py do Anexo 10.
A lógica implementada no teletransporte que se encontra no Anexo 10, é controlada por uma
script python teleport.py que quando a colisão com a esfera é positiva, transporta-a para a ultima
plataforma do nível. O seu funcionamento principal é obter a posição da esfera, e desloca-la do
teletransporte emissor (Port1), para o recetor (Port2).(Guedes 2015)
4.4.3 3ª Plataforma (Perseguição e Universo)
É chegada a última fase do jogo. Depois de feito o teletransporte da esfera para a última
plataforma que pode ser vista nas Figura 4.29 e Figura 4.28 seguintes.
Figura 4.27 – Teletransporte
32
O tema escolhido para a última plataforma, foi decidido que queríamos um ambiente relacionado
com o universo e as suas adversidades, em que os inimigos do utilizador são meteoritos que caem
em períodos de tempo nas cores impossibilitando de as obter e acabar o nível. A Figura 4.28
como se pode observar é a fase de obter a cor verde para completar a sequência da esfera e
assim procurar a maneira de trocar para o último sólido que será o cone.
Na Figura 4.30 vê-se uma estrela que é o objeto que permite após colisão trocar de imediato de
sólido em que o módulo python TrocarFig é o responsável para esse efeito e pode ser analisado
no Anexo 11. A estrela possui uma animação no eixo dos Y que desce até á plataforma de modo
a que a esfera a consiga atingir e que deixa de existir assim que a troca se realiza.
Figura 4.29 – Última plataforma (Perseguição e Universo) Figura 4.28 – Última plataforma na câmara da esfera
Figura 4.30 – Estrela
33
Entretanto os meteoritos já iniciaram a sua contagem para caírem sobre as cores para
impossibilitar a obtenção das cores pelos sólidos. A lógica implementada para o conseguir é
apresentada na Figura 4.31.
Quando a esfera colide com a plataforma que possui uma propriedade timer, vinda do
teletransporte faz reiniciar o tempo e assim se inicia uma contagem com os tempos
estabelecidos na Figura 4.31.Quando o valor do timer atingir os 8,22,30,35 segundos os planos
que suportam os meteoritos desaparecem e que os irá fazer cair sobre as respetivas cores,
cabendo ao utilizador obtê-las a todas antes dos meteoritos as “destruírem”. (Anexo 13)
Tudo isto é uma combinação da máquina de estados do BGE, em que os restantes estados e um
exemplo de uma script responsável por desativar as cores se encontram no Anexo 12. (Guedes
2015)
Feita a troca de sólidos, entra em jogo o cone que tem por objetivo pintar as restantes cores que
sobram pela ordem correta e terminar o jogo, no entanto o meteorito que está no centro da
plataforma começa a sua perseguição ao cone dificultando o seu objetivo como demonstra a
Figura 4.32.
Figura 4.31 – Lógica da plataforma
Figura 4.32 – Perseguição
34
A lógica para a implementação do último inimigo do jogo é mostrada no Anexo 14, mas o
módulo python switch2 do Anexo 11 é o controlador de todo o processo. É enviada uma
mensagem num sensor para um estado que se encontra em espera para ser ativado por um
sensor delay, que conectado ao módulo irá por sua vez ativar um atuador steering que serve
para perseguir objetos até á colisão.
Escapando a todos os perigos e dificuldades que o nível proporcionou ao concluir a sequência
de cores do cone, são iniciadas duas animações, na cor preta que irá permitir a subida (Anexo
15) para a porta de saída do nível que por sua vez contém também uma animação em que se
abrem as portas para a conclusão do nível dois. Essas animações são criadas com mensagens
ligadas a atuadores action que por sua vez são recebidas no cone como sensores property.
A Figura 4.33 representa assim a atuação das animações referidas e a possibilidade de concluir
o nível e o jogo por parte do utilizador.
Figura 4.33 – Finalização do nível e do jogo
35
4.5 Plataforma Mobile Android
Acabado o jogo que foi desenvolvido para PC e para além dos objetivos inicialmente
estabelecidos, com o aconselhamento do nosso orientador pareceu-nos óbvio a partir de uma
certa altura, devido as próprias características do jogo, abordar a parte mobile. Foi então feita
pesquisa sobre este tema no qual se pode retirar algumas conclusões positivas e negativas.
Pelo lado positivo destaca-se o facto de se a pessoa que desenvolver um jogo em Blender não
terá que saber programação android para conseguir fazer rodar o seu jogo num dispositivo,
mas pelo lado negativo pode-se concluir que a programação android em Blender se encontra
numa fase ainda em desenvolvimento pelo que apresenta muitas falhas, entre as quais não
aceitar textura, não aceita logic bricks e muito menos aceita python, o que resulta apenas numa
experimentação muito básica como a da Figura 4.37, em que apenas é apresentado um plano e
um cubo em que não é possível sequer movimentá-lo. As fontes que foram investigadas apenas
conseguem fazer rodar a câmara, e fazer o pressionar num objeto. Essas funções são
desenvolvidas com uma linguagem própria que se pensa ser do OgreKit e do LuaEditor.
Foi decidido seguir uns tutoriais que existem num canal do youtube, que nos pareceu ser o mais
fiável, e que apresentava algum resultado concreto. (hhhnzw 2012) (hhhnzw(touch) 2012)
Foi também iniciada uma thread no blog blenderartists (patrickguedes 2015), que entanto não
foi completamente esclarecedor sobre a possibilidade do desenvolvimento de jogos feitos no
BGE para android.
Seguindo as fontes referidas anteriormente tiveram que ser seguidos alguns passos
importantes:
Download e instalação do addon Gamekit(hhhnzw(addon) 2012)
Download do Lua Editor
Download AppOgrekit
Download e instalação do Eclipse(Network 2015)
Download e instalação do Android SDK(Crafton 2012)
Download e instalação do Android Ecplise Plug-in(Collins 2012)
36
Feitos todos os downloads e instalações, foi criado um projeto no BGE de um cubo com logic
bricks para se mover que se pode ver na Figura 4.35.
Seguindo obrigatoriamente a ordem expressa na Figura 4.35, ir-se-á obter a Figura 4.34 que é
um standalone player do Gamekit, e caso seja aceite, isto é sejam apresentados os objetos
corretamente o jogo poderá ser exportado para um sistema android.
O processo para depois criar um projeto encontra-se no Anexo 16 e que resulta na Figura 4.36.
Figura 4.34 – OgreKit Figura 4.35 – Gamekit
Figura 4.36 – Finalizar projeto
37
Basicamente o processo passa por abrir o eclipse, criar um novo projeto de Android Project from Existing Code no separador Android, de seguida procurar a pasta onde se encontra o projeto Blender no caso GameKit-Android e fazer finish. Para concluir liga-se o dispositivo android ao computador, e basta seguir os passos enumerados na Figura 4.36 que irá resultar então na Figura 4.37.
Figura 4.37 – ScreenShot Android
39
Capítulo 5
5 Conclusões
O interesse por este projeto surgiu pelo facto de estar ligado a uma indústria bastante
apelativa, como é a indústria dos vídeo jogos, e com isso entender melhor as etapas de criação
de um jogo assim como os problemas que podem surgir independentemente da plataforma em
que estejamos a trabalhar. Para a sua realização, foi necessário inicialmente um trabalho de
pesquisa e aprendizagem sobre o motor de jogos do Blender assim como a sua linguagem de
scripts python, de maneira a perceber previamente o que poderia ser feito com esta
ferramenta. Com o avanço do projeto e consoante as necessidades do nosso jogo fomos
descobrindo e aplicando novas funcionalidades com o objetivo de o tornar mais apelativo e
desafiante ao utilizador.
O jogo acabou por superar as nossas expetativas inicias, na perspetiva da capacidade do BGE
pela sua robustez, funcionalidades e grafismo.
Nos testes para a plataforma mobile android que foram feitos, pudemos também concluir que
se encontra numa fase inicial do seu desenvolvimento, mas que no entanto poderá com tempo
tornar-se uma maneira eficaz de produção de jogos feitos em Blender para plataformas móveis.
Em suma, estamos muito satisfeitos com o projeto/jogo que conseguimos desenvolver e por
termos conseguido cumprir todos os objetivos que foram traçados ao longo do seu
desenvolvimento, numa perspetiva desafiante dia após dia, de modo a ultrapassar os
obstáculos que fomos encontrando.
5.1 Trabalho Futuro
Assim como em qualquer jogo, também o processo de desenvolvimento nunca estaria acabado
pois há sempre algo que pode ser melhorado ou desenvolvido, como por exemplo: desenvolver
novos níveis e por consequente novos desafios ao jogador, possibilidade de escolher o som
ambiente do jogo, escolher a dificuldade ou puder salvar e carregar o seu próprio “save”.
A parte mobile também poderia ser melhorada pelo que achamos que daria uma boa
continuação para outro possível projeto ou tese de mestrado por ser uma área que se encontra
em expansão e desenvolvimento embora ainda muito primitiva.
41
Referências Bibliográficas
Arts, C. (2009). "Blender Engine - Criando um Jogo - 11." from https://vimeo.com/2777215.
Bart. (2014, Dezembro 2014). "Blender production 'I will Escape' debuts next week on Steam." from http://www.blendernation.com/2014/12/15/blender-production-i-will-escape-debuts-next-week-on-steam/.
blender.org. "Desenvolver em Android." from http://wiki.blender.org/index.php/Doc:2.6/Manual/Game_Engine/Android.
blender.org(GameEngine). "Introduction to Game Engine." Retrieved Dezembro 2014, from http://www.blender.org/manual/game_engine/index.html.
blender.org(python). "Python, a Linguagem de Scripts." Retrieved Fevereiro de 2015, from http://wiki.blender.org/index.php/Doc:PT/2.6/Manual/Introduction/Installing_Blender/Python.
blenderartist(Racer). (2015, Janeiro 2015). "BGMC 14 | Fun Kart Racer by Thatimst3r." Retrieved Fevereiro, 2015, from http://blenderartists.org/forum/showthread.php?358916-BGMC-14-Fun-Kart-Racer-by-Thatimst3r.
blenderArtists (2013). "easyEmit - *Update* 13.06.2013."
blenderArtists(Objects) (2015). "Ojects from layers."
Caçador, F. (2014). "Desenvolvimento de videojogos já está a "fervilhar" em Portugal." Retrieved Fevereiro, 2015, from http://tek.sapo.pt/noticias/computadores/desenvolvimento_de_videojogos_ja_esta_a_fervi_1398576.html.
Collins, T. (2012). "Eclipse Android SDK and ADT download and install."
Cookie, B. (2011).
Crafton, D. (2012). "Android SDK Installation (Windows 7 32-Bit)."
Cura, H. (2015, 19 de Fevereiro de 2015). "O rumo que levam os jogos de hoje." pplware, from http://pplware.sapo.pt/jogos/o-rumo-que-levam-os-jogos-de-hoje/.
Esau, A. (2011). "Orbito Gameplay - Blender Game." Retrieved Janeiro, 2015, from https://www.youtube.com/watch?v=ZDNcOy8N9Uo.
Guedes, P. (2015). "Restart time (timer) property."
hhhnzw (2012). "Blender 3D 2.6 & gamekit Android 3D Game Test on Nexus 7."
hhhnzw(addon) (2012). "blender 3D 2.6 Gamekit addon install and test."
hhhnzw(touch) (2012). "Blender 3D gamekit Android 3D openGL touch look on nexus 7."
Manual, B. R. "Game Logic Screen Layout." Retrieved Fevereiro, 2015, from http://www.blender.org/manual/game_engine/screen_layout.html.
Network, C. (2015). "How to Install Latest Eclipse Luna (4.4.1) IDE for Java Developers in Windows 7."
opengl.org "OpenGL Shading Language."
patrickguedes (2015). "Android Game in Blender."
quitchou94. (2010). "[trailer] ColorCube 1.6 [Video File]." Retrieved Dezembro, 2014, from https://www.youtube.com/watch?v=KKK-p1TXW7A.
42
RandomPickle97(CubeInvasion). (2012). "Cube Invasion." from http://blenderartists.org/forum/showthread.php?258250-Cube-Invasion&highlight=cube.
rsl, a. (2014). "Applying Textures in Blender ".
ThaTimst3r "How to Make a Game Menu in the Blender Game Engine."
Wikipédia. (2015, Dezembro 2014). "Blender Institute." Retrieved Fevereiro 2015, from http://pt.wikipedia.org/wiki/Blender_Institute.
Wikipédia(Blender). (2015, Janeiro 2015). "Blender." Retrieved Janeiro, 2015, from http://pt.wikipedia.org/wiki/Blender.
Wikipédia(Cristal). (2015, Fevereiro 2013). "Crystal Space." Retrieved Fevereiro, 2015, from https://pt.wikipedia.org/wiki/Crystal_Space.
Wikipédia(Foundation). (2015, Dezembro 2014). "Blender Foundation." Retrieved Fevereiro, 2015, from http://pt.wikipedia.org/wiki/Blender_Foundation.
Wikipédia(Ton_Roosendaal). (2013, Abril 2013). "Ton Roosendaal." Retrieved Fevereiro, 2015, from http://pt.wikipedia.org/wiki/Ton_Roosendaal.
Wikipédia(YoFrankie). (2015, Novembro 2014). "Yo Frankie!" Retrieved Dezembro 2014, from https://pt.wikipedia.org/wiki/Yo_Frankie!
43
Anexos
timerN0.py import bge def main(): cont = bge.logic.getCurrentController() own = cont.owner cena = cont.actuators ["cena"] tempo = (13 - own ["timeLoad"]) if tempo <= 0: cont.activate(cena) main()
Anexo 1
Anexo 2
45
azulN0.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() cuboNivel0 = scene.objects ["cuboNivel0"] corAzulN0 = scene.objects ["corAzulN0"] azulNivel0 = scene.objects ["azulNivel0"] vermelhoNivel0 = scene.objects ["vermelhoNivel0"] colisao2 = cont.sensors ["colisao2"] cena = cont.actuators ["cena"] if colisao2.positive and azulNivel0 ["azul"] == True: cuboNivel0 ["cubo"] = False cuboNivel0.color = [0,0,1,True] corAzulN0.color = [0,0,1,True] vermelhoNivel0 ["vermelho"] = False cont.activate(cena) main() vermelhoN0.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() cuboNivel0 = scene.objects ["cuboNivel0"] corVermelhaN0 = scene.objects ["corVermelhaN0"] vermelhoNivel0 = scene.objects ["vermelhoNivel0"] azulNivel0 = scene.objects ["azulNivel0"] colisao1 = cont.sensors ["colisao1"] if colisao1.positive and vermelhoNivel0 ["vermelho"] == True: cuboNivel0.color = [1,0,0,True] corVermelhaN0.color = [1,0,0,True] azulNivel0 ["azul"] = True main()
excoramarela.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() own = cont.owner TemporizadorPrincipal = scene.objects ["TemporizadorPrincipal"] TemporizadorSec = scene.objects ["TemporizadorSec"] esferaprincipal = scene.objects ["esferaprincipal"] corAmarela = scene.objects ["corAmarela"]
Anexo 5
Anexo 4
46
corAmarelaSec = scene.objects ["corAmarelaSec"] corAmarelaCubo = scene.objects ["corAmarelaCubo"] collision = cont.sensors ["collision"] if collision.positive: esferaprincipal ["prop"] = True esferaprincipal.color = [1,1,0,True] corAmarela.color = [1,1,0,True] corAmarelaSec.color = [1,1,0,True] corAmarelaCubo.color = [1,1,0,True] TemporizadorPrincipal ["timer"] -= 5 TemporizadorSec ["timer"] -= 5 main() trocar.py from bge import logic def switch(cont): cont.actuators['Camera'].object = logic.getCurrentScene().objects['cuboprincipal'] def TrocarFig(cont): scene = logic.getCurrentScene() esferaprincipal = scene.objects ["esferaprincipal"] if cont.sensors['colisao'].positive and esferaprincipal ["prop"] == True: new_obj = scene.addObject("cuboprincipal",esferaprincipal, 0) esferaprincipal.sendMessage("Set_Cam_Cube", "", "CameraCubo") esferaprincipal.endObject() timer.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() own = cont.owner TemporizadorPrincipal = scene.objects ["TemporizadorPrincipal"] TemporizadorSec = scene.objects ["TemporizadorSec"] TempCubo = scene.objects ["TempCubo"] cena = cont.actuators ["cena"] tempo = (60 - TemporizadorPrincipal ["timer"]) tempo = (60 - TemporizadorSec ["timer"]) tempo = (60 - TempCubo ["timer"]) tempoJogo = round(tempo ,1) TemporizadorPrincipal.text = str(tempoJogo) TemporizadorSec.text = str(tempoJogo) TempCubo.text = str(tempoJogo) TemporizadorPrincipal.color = (0,0,1,True) TemporizadorSec.color = (0,0,1,True) TempCubo.color = (0,0,1,True) if tempoJogo >= 65: cont.activate(cena) if tempoJogo <= 0: cont.activate(cena) if tempoJogo <=5:
47
TemporizadorPrincipal.color = [1,0,0,True] TemporizadorSec.color = [1,0,0,True] TempCubo.color = [1,0,0,True] main()
força.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() own = cont.owner trackTo = cont.actuators ["trackTo"] movement = cont.actuators ["movement"] cubohole = scene.objects ["cubohole"] cuboholeDistance = own.getDistanceTo(cubohole) cont.activate(trackTo) if cuboholeDistance <= 10: cont.activate(movement) else: cont.deactivate(trackTo) cont.deactivate(movement) main() camera2.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() own = cont.owner CameraNivel1 = scene.objects ["CameraNivel1"] CameraNivel1Sec = scene.objects ["CameraNivel1Sec"] TemporizadorSec = scene.objects ["TemporizadorSec"] corAmarelaSec = scene.objects ["corAmarelaSec"] corAzulSec = scene.objects ["corAzulSec"] corVermelhaSec = scene.objects ["corVermelhaSec"] corsequencia1Sec = scene.objects ["corsequencia1Sec"] corsequencia2Sec = scene.objects ["corsequencia2Sec"] corsequencia3Sec = scene.objects ["corsequencia3Sec"] if CameraNivel1Sec ["camera"] == True: CameraNivel1Sec.setVisible(1) TemporizadorSec.setVisible(1) corAmarelaSec.setVisible(1) corAzulSec.setVisible(1) corVermelhaSec.setVisible(1) corsequencia1Sec.setVisible(1) corsequencia2Sec.setVisible(1) corsequencia3Sec.setVisible(1) if CameraNivel1Sec ["camera"] == False: CameraNivel1Sec.setVisible(0) TemporizadorSec.setVisible(0)
48
corAmarelaSec.setVisible(0) corAzulSec.setVisible(0) corVermelhaSec.setVisible(0) corsequencia1Sec.setVisible(0) corsequencia2Sec.setVisible(0) corsequencia3Sec.setVisible(0) main()
49
portao.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() Portao = scene.objects ["Portao"] own = cont.owner abre = cont.sensors ["abre"] abrir = cont.actuators ["abrir"] somPorta = cont.actuators ["somPorta"] if Portao ["props"] == True: cont.activate(abrir) cont.activate(somPorta) main()
helice.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() own= cont.owner local = True force = [0,1,0] cuboNivel2 = scene.objects ["cuboNivel2"] radar = cont.sensors["radar"] motion = cont.actuators ["motion"] sound = cont.actuators ["sound"] cont.activate(motion) #bge.logic.setLogicTicRate(50) if radar.positive: cuboNivel2.applyForce(force,local) cont.activate(sound) else: cont.deactivate(sound) main()
Anexo 6
Anexo 7
50
PerderEsferaN2.py from bge import logic def vidinha1(cont): scene = logic.getCurrentScene() own = cont.owner esferaNivel2 = scene.objects ["esferaNivel2"] spawn_point2 = scene.objects ["spawn_point2"] spawn_point4 = scene.objects ["spawn_point4"] VidaEsf1 = scene.objects ["VidaEsf1"] VidaEsf12 = scene.objects ["VidaEsf12"] colisao4 = cont.sensors ["colisao4"] colisao5 = cont.sensors ["colisao5"] colisao8 = cont.sensors ["colisao8"] Message = cont.sensors ["Message"] FogoArder = cont.actuators ["FogoArder"] if Message.positive: esferaNivel2.color = [0,0,0,True] cont.activate(FogoArder) else: cont.deactivate(FogoArder) if colisao4.positive or colisao5.positive: esferaNivel2.setVisible(0) esferaNivel2.worldPosition = spawn_point2.worldPosition esferaNivel2.setVisible(1) esferaNivel2 ["lives"] -= 1
Anexo 8
Anexo 9
51
if colisao8.positive: esferaNivel2.setVisible(0) esferaNivel2.worldPosition = spawn_point4.worldPosition esferaNivel2.setVisible(1) esferaNivel2 ["lives"] -= 1 if esferaNivel2 ["lives"] == 2: VidaEsf1.setVisible(0) VidaEsf12.setVisible(0) def vidinha2(cont): scene = logic.getCurrentScene() spawn_point2 = scene.objects ["spawn_point2"] spawn_point4 = scene.objects ["spawn_point4"] own = cont.owner colisao5 = cont.sensors ["colisao5"] esferaNivel2 = scene.objects ["esferaNivel2"] VidaEsf22 = scene.objects ["VidaEsf22"] VidaEsf2 = scene.objects ["VidaEsf2"] if esferaNivel2 ["lives"] == 1: VidaEsf22.setVisible(0) VidaEsf2.setVisible(0) def vidinha3(cont): scene = logic.getCurrentScene() spawn_point2 = scene.objects ["spawn_point2"] spawn_point4 = scene.objects ["spawn_point4"] own = cont.owner colisao5 = cont.sensors ["colisao5"] cena1 = cont.actuators ["cena1"] esferaNivel2 = scene.objects ["esferaNivel2"] VidaEsf32 = scene.objects ["VidaEsf32"] VidaEsf3 = scene.objects ["VidaEsf3"] if esferaNivel2 ["lives"] == 0: VidaEsf32.setVisible(0) VidaEsf3.setVisible(0) cont.activate(cena1)
52
pintarLaranjaN2.py import bge def main(): cont = bge.logic.getCurrentController() scene = bge.logic.getCurrentScene() own = cont.owner esferaNivel2 = scene.objects ["esferaNivel2"] laranja = scene.objects ["laranja"] azul = scene.objects ["azul"] Port1 = scene.objects ["Port1"] TorusPort1 = scene.objects ["TorusPort1"] CorPintarEsf22 = scene.objects ["CorPintarEsf22"] CorPintarEsf2 = scene.objects ["CorPintarEsf2"] colisao3 = cont.sensors ["colisao3"] if colisao3.positive and laranja ["laranja1"] == True and esferaNivel2 ["prop"] == False: esferaNivel2.color = [255,1,0,1] esferaNivel2 ["prop"] = True CorPintarEsf2.color = [255,1,0,1] CorPintarEsf22.color = [255,1,0,1] azul ["azul1"] = False Port1.setVisible(1) TorusPort1.setVisible(1) main() Teleport.py from bge import logic cont = logic.getCurrentController() own = cont.owner scene = logic.getCurrentScene() obj = scene.objects[own['para']] esferaNivel2 = scene.objects['esferaNivel2'] ambientePlat3 = scene.objects ["ambientePlat3"] if own['Ativa'] == 0 and cont.sensors['colisao1'].positive: esferaNivel2.worldPosition = [obj.worldPosition[0],obj.worldPosition[1],obj.worldPosition[2]+1] obj['Ativa'] = 1 ambientePlat3.setVisible(1)
Anexo 10
53
from bge import logic def switch(cont): cont.actuators["Camera"].object = logic.getCurrentScene().objects["coneNivel2"] def switch2(cont): cont = logic.getCurrentController() own = cont.owner scene= logic.getCurrentScene() coneNivel2 = scene.objects['coneNivel2'] Delay = cont.sensors['Delay'] Follow = cont.actuators['Follow'] if Delay.positive: Follow.target= coneNivel2 cont.activate(Follow) else: cont.deactivate(Follow) def TrocarFig(cont): scene = logic.getCurrentScene() esferaNivel2 = scene.objects ["esferaNivel2"] estrela = scene.objects ["estrela"] if cont.sensors["colisao7"].positive and esferaNivel2 ["prop"] == False: new_obj = scene.addObject("coneNivel2",esferaNivel2, 0) new_obj.worldOrientation = [0,0,0] esferaNivel2.sendMessage("Set_Cam_Cube", "", "CameraSeguirCone") esferaNivel2.sendMessage("Set_Pedra_Cone", "", "meteoro5") esferaNivel2.endObject() estrela.endObject()
Anexo 11
Anexo 12
54
def meteorito3(cont): scene = logic.getCurrentScene() meteoro3 = scene.objects ["meteoro3"] verdeFinal = scene.objects ["verdeFinal"] colisao = cont.sensors ["colisao"] if colisao.positive: verdeFinal ["verde"] = False verdeFinal.color = [0,0,0,True]
Anexo 13
Anexo 14
Top Related