Jogo do NEEC
Jogo do NEEC Primeiramente, criamos uma nova Actividade File > New > Class
Source folder: JogoDoNEEC/src Package: org.neecist.jogodoneec Name: JogoDoNEEC Superclass: android.app.activity Browse > Procurar Activity > OK
Obtemos: Jogo do NEEC
Jogo do NEEC (2) E registamo-la no Android Manifest Código no checkpoint 1
Acabando a parte anterior Botão Bora lá vai chamar nova Actividade. Passa dificuldade e nome por Bundle. Menu_principal.java, mudar método submitdata para: Código no checkpoint: 1
Acabando a parte anterior O Menu já chama a nova Actividade. Já se pode criar o jogo
Extending the View Vamos criar a nossa View para o jogo Source folder: JogoDoNEEC/src Package: org.neecist.jogodoneec Name: GameView Superclass: android.view.view
Custom Views Todas as Vistas disponíveis na ADT são extensões da classe View. Desta forma, podemos criar Custom Views fazendo extend da classe View. Para exemplificarmos algumas coisas que podemos fazer com uma Custom View, vamos usar uma para criar o Jogo do NEEC
Extending the View Obtém-se: Para corrigir o erro, carregar em cima de GameView e carregar na solução proposta para criar o constructor.
Criando uma Vista programaticamente A GameView será criada na GameActivity Criamos uma nova variável que irá guardar a GameView
Criando uma Vista programaticamente (2) No JogoDoNEEC.java fazer override à oncreate Mete em Fullscreen Criámos um objecto do tipo GameView Código no Checkpoint: 2 E depois escolhemos essa Vista como aquela que define a UI nesta actividade
Definir o fundo CTRL+SHIFT+O para importar a package Bitmap Na GameView.java adicionar Criámos o bitmap do fundo Carregamos os recursos O método decoderesources da class BitmapFactory cria um objecto do tipo Bitmap com a imagem escolhida e retorna a sua referência Finalmente desenhamos o bitmap na posição 0, 0
Parece estar bom! Resultado?
Coordenadas A posição de um bitmap no ecrã é a posição do seu canto superior esquerdo No entanto a posição de texto escrito com o método drawtext é o canto inferior esquerdo.
Mais alguns Bitmaps Adicionar na GameView.java
O tamanho da imagem não se adapta ao tamanho do ecrã Convém tratar disto! O que obtemos?
Mudar na GameView.java Código no Checkpoint 3 Primeiro carregamos o fundo, e calculamos um factor de escala com base nas dimensões do ecrã para redimensionar os restantes Bitmaps. Carregar restantes bitmaps Obter dimensões do ecrã Redimensionar Bitmaps
Mudar na GameView.java Código no Checkpoint 3
Redesenhando Já faz o resize correcto aos Bitmaps
Adicionando a pontuação e o tempo Mudar na GameView.java Mudar na GameView.java, no final do constructor GameView() Código no Checkpoint 4
Adicionando a pontuação e o tempo Mudar na GameView.java E utilizámos o método drawtext() da classe Canvas para desenhar os pontos e o tempo em cada momento. Código no Checkpoint 4
Paint Classe que contém informação sobre o estilo e a cor do que vamos desenhar. Métodos úteis: void setstrokewidth(float width); void setstyle(paint.style style); void settextsize(float textsize); void setcolor(int color); Paint.Style.FILL Paint.Style.FILL_AND_STROKE Paint.Style.STROKE
A Pontuação e o tempo restante já são apresentados Voltando a correr
Já temos no ecrã o valor do tempo. Agora temos de arranjar uma Thread que faça de temporizador e vá actualizando este valor. Vamos adicionar já esta variável, que mais à frente vai ser-nos útil Definimos a Thread TimerThread, que vai ser o nosso temporizador. Desta vez optámos por criar uma nova subclasse em vez subclasse anónima, como no temporizador do SplashScreen. (Apenas para mostrar que é possível das duas formas J ) Código no Checkpoint 5
Adicionando o Relógio Criamos o objecto, e metemos no final do construtor da GameView.java: Código no Checkpoint 5
Adicionando o Relógio O Relógio ainda não muda o seu valor
DRAW O nosso temporizador está a correr e a actualizar os valores. Mas não são actualizados no ecrã Porquê? Método ondraw: vai ser chamado quando a Vista está visível pela primeira vez ou quando chamamos um dos seguintes métodos: Invalidate() postinvalidate() Slide anterior, 2014 Deste que a Vista ficou visível pela primeira vez nunca mais foi actualizada. Se calhar seria boa ideia actualizar num determinado período de tempo!
Adicionar antes do constructor da GameVIew.java DRAW (2) Adicionar às variáveis da classe 59 FPS Adicionar ao final do construtor Código no Checkpoint 6
Adicionando o Relógio O Relógio já muda de valor!
Receção da informação enviada pelo menu Adicionar no início do constructor da GameVIew.java Obtemos o Bundle passado à Activity e extraímos os dados Definimos a velocidade de queda dos objetos de acordo com a velocidade Código no Checkpoint 7
Game Over: E ainda nem jogámos! Queremos que quando o contador chegue a 0, apareça um ecrã de Game Over. Para isso temos apenas de fazer as seguintes pequenas alterações: Mudar no ondraw da GameView.java Código no Checkpoint 7
Game Over: E ainda nem jogámos! (3)
O que é que vai cair? Um FallingObject! Esta classe vai ter: Posição (x, y) Dimensões (width, height) Velocidade (speedy) Uma imagem (bitmap) Objecto Random (para gerar posições aleatórias) Métodos responsáveis por obter/modificar cada uma destas variáveis Método que verifica se um determinado ponto faz parte deste objecto Método que faz reset da posição do objecto
Primeiramente, criamos uma nova Classe File > New > Class
Source folder: JogoDoNEEC/src Package: org.neecist.jogodoneec Name: FallingObject Superclass: java.lang.object
O que é que vai cair? Um FallingObject! Código no Checkpoint 8 Usado na função de reset da posição para gerar posições aleatórias
O que é que vai cair? Um FallingObject! O constructor recebe uma referência para um objeto Bitmap e um objeto Random, para evitar serem criadas instâncias para cada objecto FallingObject criado. Código no Checkpoint 8
O que é que vai cair? Um FallingObject! Retorna valor de y Actualiza a posição, somando a velocidade à posição Desenha a imagem na posição correspondente Código no Checkpoint 8
O que é que vai cair? Um FallingObject! Detectar se coordenada está sobre o FallingObject: Recebe coordenada; Retorna true se a coordenada está contida e false se não estiver. Código no Checkpoint 8
O que é que vai cair? Um FallingObject! Reset da Posição: Recebe dimensões do ecrã; X irá tomar um valor contido entre 0 e a largura do ecrã; Y irá ficar acima do ecrã. Objeto rand que foi passado pelos al Código no Checkpoint 8
Criar os FallingObject Array com Objectos: Array com 9 objectos que dão pontos e 9 objectos que tiram pontos (good e bad) X inicial irá tomar um valor contido entre 0 e a largura do ecrã; Y inicial irá ficar acima do ecrã. Adicionar às variáveis da classe GameView.java Código no Checkpoint 8
Inicializar os Vectores de Objetos É necessário gerar números aleatórios por isso adicionar nas variáveis da classe: No constructor da GameView adicionar (a seguir a serem inicializados os Bitmap): O objeto do tipo Random será passado aos FallingObject Código no Checkpoint 8
Inicializar os Vectores de Objectos (3) No constructor da GameView, adicionar no final, antes de iniciar os threads: Cria um novo FallingObject Coloca- o numa posição aleatória Código no Checkpoint 8
Desenhar os FallingObject Na GameView: Actualizar a posição e desenhar os Objectos Adicionar a seguir a desenhar o temporizador no método ondraw, ainda dentro do if Se sair do ecrã, faz reset da posição Código no Checkpoint 8
Detectar Toque Fazer Override à ontouchevent na GameView: Recebe MotionEvent Obter coordenadas x e y Se for um evento de toque: Verificar se objector foi pressionado; Repôr posição do objector; Somar pontuação específica Código no Checkpoint 8
Testar Neste momento já temos um jogo minimamente funcional: Game Loop onde são feitos updates às instâncias do jogo e são desenhadas; É tratado o input do utilizador; Falta só terminar o jogo de forma correcta: Detectar que se está a sair da Activity; Parar os threads na GameView.
Parar threads Detectar que se está a sair da GameActivity Fazer Override à função ondestroy na Activity JogoDoNEEC: Mete o jogo em modo parado Espera que os Threads terminem Código no Checkpoint 9
Parar threads (2) Adicionar setgameisrunning() Na GameView adicionar: Código no Checkpoint 9
Parar threads (3) Adicionar stopthreads Na GameView adicionar: thread.join() Espera que o thread termine e só depois prosegue com o código Espera pelo timer_thread e pelo drawing_thread Código no Checkpoint 9 Nota: O jogo continua a correr caso se saia da aplicação e esta ainda estiver a correr.
FIM