python bge

306

Click here to load reader

Upload: jlbbclick21combr

Post on 20-Jun-2015

551 views

Category:

Documents


9 download

TRANSCRIPT

Page 1: Python BGE

Python & BGE

Criando jogos com o Blender

Brutto AVT (criação)Cerberus_1746 (revisão)

Page 2: Python BGE

Antes de começar...Tudo tem que começar em algum lugar, certo? Basta analisar a imagem ao lado para ver a evolução de alguns jogos clássicos.

É bem provável que você se lembre de alguns desses. Talvez lembre até mesmo de fases inteiras.

Page 3: Python BGE

Antes de começar...Este é o primeiro Super Mario, que podia ser jogado num NES lá por 1985.

Mesmo sendo de gráficos simples, o jogo consegue te prender na frente da tela por algum tempo.

Por que? Simplesmente pelo fato de que ele foi muito bem planejado e desenvolvido.

Page 4: Python BGE

Definindo um objetivoVocê não pode criar algo e esperar que vá dar certo, se não tiver uma idéia bem clara do que pretende fazer.

Ao processo de definição de um projeto é dado o nome de pré-produção ou planejamento.

Page 5: Python BGE

Definindo um objetivo

Antes de qualquer coisa, faça uma pergunta a si mesmo:

"Qual o meu objetivo?"

É isso que o guiará até o final do projeto. Caso as coisas comecem a ficar confusas, basta se lembrar do seu objetivo inicial.

Portanto, devemos ter algumas coisas em mente.

Page 6: Python BGE

Dando forma ao objetivo

Qual o estilo do meu jogo? Plataforma, luta, RPG, corrida, futebol...

Qual será meu público alvo? Jogadores casuais, jogadores freqüentes, jogadores hardcore...

Os inimigos ou adversários terão inteligência artificial?

Qual o tamanho do meu jogo? Ele será dividido por fases?

O jogador pode escolher qual fase quer jogar? Será um jogo multiplayer?

Page 7: Python BGE

Dando forma ao objetivo

O que mais?Pense por alguns minutos nas características básicas...

Page 8: Python BGE

Dando forma ao objetivoTambém é necessário fazer um planejamento mais detalhado. Pode não parecer, mas isso nos economizará tempo no futuro.

A idéia é, basicamente, que quando mais tempo se gasta planejando, menos tempo é necessário para desenvolver e corrigir erros.

Ou você realmente acha que Cabral descobriu o Brasil por acidente?

Page 9: Python BGE

Um planejamento mais elaboradoNesta etapa preciamos ser bem mais precisos do que fomos no planejamento inicial.

Ao final desta etapa, deveremos saber exatamente o que e como fazer.

Portanto, agora você deve pensar nos desafios que o jogador irá enfrentar, quem e como serão os inimigos, como serão os cenários, etc...

Page 10: Python BGE

Coletando recursosMuitas vezes não temos tempo ou menos habilidade para criar a trilha sonora, as texturas, etc.

Nesses casos, o melhor é tirar proveito de bibliotecas (legais) de sons, imagens, etc. Eis algumas que recomendo:

http://www.grungetextures.com/ (texturas)http://www.jamendo.com/br/ (músicas)http://www.blender-materials.org/ (materiais)http://e2-productions.com/repository/index.php (modelos)http://opengameart.org/ (mix)

Page 11: Python BGE

Pronto? Ainda não!Agora que temos o plano completo (espero que sim), eu devo lhe fazer uma pergunta:

Você sabe programar (de preferência em Python)?

Caso já tenha conhecimento, pule alguns slides, caso contrário devo lhe apresentar a uma coisa chamada Lógica de Progamação antes disso.

Page 12: Python BGE

Lógica de programação

A definição de "lógica", segundo o dicionário Michaelis:

"1 Modo de raciocinar tal como de fato se exerce:Lógica natural. 2 Filos Estudo que tem por objeto determinar quais as operações que são válidas e quais as que não o são:Lógica formal, que trata dos conceitos, juízos e raciocínios, independentemente de seu conteúdo. Mais modernamente, análise das formas e leis do pensamento, seja do ponto de vista racionalista e crítico, seja daquele em que se descreve a experiência: Lógica genética, lógica das ciências, lógica simbólica, lógica matemática."

Page 13: Python BGE

Lógica de programação

Logo, lógica de programação refere-se a como fazer as coisas acontecerem, seguindo por caminhos dedutivamente corretos (verdadeiros).

Resumindo: lógica é dedução. Agora, não podemos confundir dedução com adivinhação ou tentativa e erro. Dedução é um processo racional, no qual temos um conjunto de possibilidades e, usando nosso conhecimento, vamos eliminando as que acharmos serem incorretas até sobrarem uma ou mais.

No caso de sobrar mais do que uma, vamos sempre pela melhor opção.

Page 14: Python BGE

Lógica de programação

Um exemplo: quem é o irmão do pai da mãe da minha sobrinha?

Se você respondeu "meu tio", parabéns! Você atende ao requerimento mínimo necessário para se tornar um programador: saber pensar logicamente.

Vamos analisar um pouco sua resposta. Como você tem certeza de que é seu tio e não seu avô? Ora, pelo seu conhecimento! Você sabe a definição de sobrinho, pai, mãe e irmão, certo?

Page 15: Python BGE

Lógica de programação

Agora outro exemplo: como proceder para trocar uma lâmpada?

A resposta pode variar de pessoa pra pessoa, pois graças a Deus somos todos diferentes e também raciocinamos de jeitos diferentes. A base de tudo? Conhecimento e experiência!

O que sua experiência e/ou conhecimento sobre trocas de lâmpadas lhes mandam responder? Bem, os meus dizem o seguinte...

Page 16: Python BGE

Lógica de programação

1. Certificar-se de que o interruptor está desligado2. Subir numa cadeira/escada para alcançar o bocal3. Remover a lâmpada queimada4. Colocar a lâmpada nova5. Descer da cadeira/escada6. Ligar o interruptor

Ao processo de definir algo de acordo com os próprios conhecimentos ou a necessidade do projeto dá-se o nome de abstração.

Page 17: Python BGE

Lógica de programaçãoJá ouviu falar em arte abstrata? Aquele monte de borrões que ninguém entende?

Bem, arte abstrata nada mais é do que o conceito do artista sobre determinado assunto. Como eu disse, todos pensam de forma diferente, assim como todos definem as coisas de modo diferente também.

Em resumo: abstração é a sua definição para uma determinada situação, objeto, etc.

Page 18: Python BGE

Lógica de programação

Na minha abstração sobre a troca da lâmpada, eu não levei em conta possíveis problemas que possam acontecer. Dê uma olhada:

1. Certificar-se de que o interruptor está desligado (se não estiver, desligar)

2. Subir numa cadeira/escada para alcançar o bocal3. Remover a lâmpada queimada4. Colocar a lâmpada nova5. Descer da cadeira/escada6. Ligar o interruptor

Page 19: Python BGE

Lógica de programação

Notou a diferença no primeiro passo? Eu impus uma condição para que a troca continuasse, já que ninguém gosta de levar choque.

Outra situação seria esta:

Subir numa cadeira/escada para alcançar o bocal. Se não alcançar, procurar um objeto mais alto para subir.

Notou que conforme avançamos no raciocínio, estamos dividindo nosso problema em problemas menores?

Page 20: Python BGE

Lógica de programação

Não se programa algo de uma vez só num único e gigantesco código. Isso não funcionaria de verdade!

É por isso que é tão importante separar nosso problema maior em pequenos problemas, agrupá-los e resolvê-los um a um.

Você pode não ter percebido, mas foi exatamente isso que fizemos no planejamento do nosso jogo. Tratamos as coisas separadamente de forma a cobrir nosso jogo completo.

Entretando, não acaba por aí. Como vamos fazer para carregar a fase correta que o jogador escolher em nosso jogo, por exemplo?

Page 21: Python BGE

Lógica de programação

Depois dessa breve introdução ao raciocínio lógico, estamos prontos para começar a pensar como programadores de verdade.

Senhoras e senhores, lhes apresento o fluxograma!

Page 22: Python BGE

Lógica de programaçãoUm fluxograma, nada mais é do que uma representação visual de um processo lógico.

Ele nos ajuda a ter uma noção melhor da nossa própria linha de raciocínio.

Embora não iremos utilizar fluxogramas no nosso projeto, é bom saber o que cada símbolo representa.

Page 23: Python BGE

Lógica de programação

Terminal: indica o início e o fim do processo Entrada ou Saída: troca de dados com usuário

Processo: cálculo ou processamento de dados

Condição: compara valores e devolve "sim" ou "não"

Conexão: ligação de dois pontos no fluxograma

Sabendo isso, veja se consegue entender o fluxograma do slide anterior.

Page 24: Python BGE

Lógica de programação

Existem mais alguns símbolos, mas por hora, os que vimos já estão de bom tamanho para que possamos seguir adiante.

Além da representação visual (fluxograma), também é possível fazer uma representação textual de um processo. A esse texto damos o nome de algoritmo.

Finalmente, um algoritmo que é criado conforme uma linguagem de programação é chamado código-fonte.

Page 25: Python BGE

Lógica de programação

Os algoritmos obedecem a alguns padrões básicos que iremos ver nos próximos slides, por hora quero que lembre de algo que foi visto anteriormente:

"Subir numa cadeira/escada para alcançar o bocal. Se não alcançar, procurar um objeto mais alto para subir."

Como pode-se notar, temos uma condição para que o processo continue. Nos algoritmos, condições são representadas pela palavra Se.

Page 26: Python BGE

Lógica de programação

Logo, o fragmento de algoritmo do exemplo ficaria assim:

faça (Subir numa cadeira/escada para alcançar o bocal);Se (não alcançar) então faça (procurar um objeto mais alto para subir);Fim Se;

As primeiras regras aqui são:1. Nomes reservados (Se, então) sempre em destaque2. Parâmetros para o Se sempre entre parênteses3. Todo Se, deve ser terminado com um então4. Toda instrução deve terminar com ponto e vírgula5. Vamos deixar o Fim Se para mais tarde...

Page 27: Python BGE

Lógica de programação

O termo "nomes reservados" refere-se a todas as palavras que fazem parte do conjunto de comandos. Você não poderia ter uma ação (função) chamada "Se", já que esta palavra é reservada.

Alguns desses comandos são funções, ou seja, eles recebem valores de entrada, os processam e retornam um valor de saída. Esse é o caso do Se. Os valores de entrada são chamados parâmetros.

Note que o Se não termina com ponto e vírgula, pois ele não é uma instrução e sim uma condição.

Page 28: Python BGE

Lógica de programação

Antes de continuar, é necessário que conheçamos os tipos de dados básicos que podemos utilizar. São eles:

Inteiro (-1, 0, 1, 2, ...)Decimal (-1.5, 0.2, 1.55, ...)Caracteres ('a', '$', 'blá blá blá', ...)Lógicos (Verdadeiro, Falso)

Com esses tipos de dados chamados "primitivos" e um pouco de conhecimento das regras (sintaxe) dos algoritmos, podemos criar processos bastante complexos.

Page 29: Python BGE

Lógica de programação

De nada adianta poder trabalhar com vários tipos de dados, se não temos como guardá-los, certo? É aí que entram as variáveis.

Lembra-se do X da matemática? Podemos fazer uma analogia dele com as variáveis dos algoritmos. Assim como na matemática, ela não precisa se chamar necessariamente 'X'.

Podemos dar qualquer nome a uma variável, desde que esteja dentro das regras, é claro!

Page 30: Python BGE

Lógica de programação

Inteiro x = 2;Inteiro y = 3;Inteiro z = x + y;

Esse fragmento cria três variáveis do tipo inteiro: x, y e z, sendo que x é igual a 2, y é igual a 3 e z é igual a soma de x e y.

A regra aqui é:Sempre colocar o tipo de dado antes do nome da variável, usar o símbolo de igualdade para atribuir o valor e terminar com ponto e vírgula.

Page 31: Python BGE

Lógica de programação

Inteiro x = 2;Inteiro xis = x;Caractere letraA = 'a';Lógico mentira = Falso;Decimal real = 1.45;

Mais algumas regras:1. Nome de variável sempre em letra minúscula. Caso seja

composto, não usar espaços e sim a primeira letra da outra palavra em maiúscula.

2. Caso seja do tipo Decimal, não usar vírgula, mas sim ponto para indicar o valor decimal.

Page 32: Python BGE

Lógica de programação

Já estamos quase perto de fazer nosso primeiro algoritmo completo. Só nos falta saber como eles começam e terminam.

As palavras são Início e Fim. Tudo o que estiver entre isso é chamado de "bloco". Lembra do Fim Se? Pois bem, agora vou explicá-lo.

O algoritmo com um todo é chamado de "bloco principal" (o processo em si), entretanto o Se também deve ser seguido por um bloco, pois ele deve ter algo para executar caso a condição informada seja verdadeira. Quando a condição é falsa, ele simplesmente pula esse bloco.

Page 33: Python BGE

Lógica de programação

Eis um algoritmo completo:

Início AlgoritmoInteiro a = 10;Se (a > 10) então Escreva (a, " é maior do que 10");Fim SeFim Algoritmo

Note que o bloco Se não tem um Início. A regra diz que o início do bloco Se é a palavra então. Outra regra é: exceto para o bloco principal (Algoritmo), toda instrução dentro de bloco deve ser identada (4 espaços em branco, ou 1 tabulação antes).

Page 34: Python BGE

Lógica de programação

Outra coisa inédita:Escreva (a, " é maior do que 10");

A função Escreva é responsável por dizer algo ao usuário. No caso que o valor da variável 'a' é maior que 10.

Quando se quer colocar uma variável junto ao retorno (entre aspas) para o usuário, é necessário separá-la do resto da saída com uma vírgula.

Page 35: Python BGE

Lógica de programação

Igualmente temos:Leia (a);

Essa função é responsável por atribuir à variável 'a' um valor informado pelo usuário. O valor antido de 'a' será substituído pelo novo.

Page 36: Python BGE

Lógica de programação

É possível agrupar várias estruturas de condição, por exemplo:

Se (a > 10) então Escreva (a, " é maior que 10");Fim SeSenão Se (a > 5) então Escreva (a, " é maior que 5"); Fim Se Senão Escreva (a, " não é maior que 5 ou 10); Fim SenãoFim Senão

Page 37: Python BGE

Lógica de programação

Também é possível agrupar várias condições dentro de um mesmo Se. Neste caso, elas serão comparadas pelos operadores e e ou.

Se (a == b e b == 2) entãoSe (a ==b ou b == 2) então

O operador e soma duas condições, ou seja, ambas tem que ser verdadeiras para que o Se seja verdadeiro. No ou, basta que apenas uma das duas seja verdadeira.

Page 38: Python BGE

Lógica de programação

O Senão é o bloco que representa o falso Se, ou seja, caso o Se retorne falso, o bloco Senão será executado.

Pela regra, devemos usar o Senão apenas para um Se e logo depois dele, ou seja, o Senão deve vir logo depois do Fim Se.

Pode-se também combinar os dois para obter condições mais complexas.

Page 39: Python BGE

Lógica de programação

Se (a > 10) então Escreva (a, " é maior que 10");Fim SeSenão Se (a > 5) então Escreva (a, " é maior que 5");Fim Senão SeSenão Escreva (a, " é menor que 5 ou 10");Fim Senão

Esse trecho faz exatamente a mesma coisa que o anterior. Note que Senão Se não é nem Se, nem Senão, mas sim uma nova palavra.

Page 40: Python BGE

Lógica de programação

E se quiséssemos saber se a é maior ou igual a 10? Pois bem, lhe apresento os operadores:

Atribuição (a = 10): atribui um valor a uma variávelIgualdade (a == 10): compara se dois valores são iguaisMaior (a > 10): compara se um valor é maior que outroMenor (a < 10): compara se um valor é menor que outroMaior ou igual (a >= 10): compara se um valor é maior ou igual a outroMenor ou igual (a <= 10): compara se um valor é menor ou igual a outroDiferença (a != 10): compara se um valor é diferente do outro.

Page 41: Python BGE

Lógica de programação

Uma coisa importante a esclarecer: o operador de diferença não existe de verdade!

Ele é, na realidade, o operador de igualdade com retorno invertido. É isso que o operador de negação (!) faz. inverte o valor de uma variável do tipo Lógica.

Supondo que a seja igual a 10, temos:

a == 10 é igual a Verdadeiroa != 10 é igual a Falso

Page 42: Python BGE

Lógica de programação

Mais uma regra de algoritmos:

Enquanto (a < 10) faça a = a - 1; Escreva (a);Fim Enquanto

Isso é uma estrutura de repetição que irá subtrair 1 do valor de 'a' e mostrar o valor atual para o usuário até que a condição seja satisfeita. No caso, até a ser menor que 10.

Page 43: Python BGE

Lógica de programação

Igualmente temos:

Repita a = a - 1; Escreva (a);até que (a < 10);

Esse trecho faz o mesmo que o anterior, é apenas uma outra estrutura de repetição. Note que o até que termina com ponto e vírgula, pois não existe Fim Repita. Caso não haja uma condição para o bloco parar, o código irá se repetir eternamente podendo haver perdas consideráveis de desempenho

Page 44: Python BGE

Lógica de programação

Uma outra forma:

Para a de 100 até 9 faça Escreva (a);Fim Para

Novamente uma estrutura que diminui em 1 o valo de a até ela ser menor que 10 (igual a 9 no caso). A diferença do Para é que ela é uma repetição contada, ou seja, o valor de 'a' é atribuído dentro do próprio comando (100).

Page 45: Python BGE

Lógica de programação

Também é possível fazer:

Para a de 100 até 9 passo 2 faça Escreva (a);Fim Para

Nesse caso, o valor de 'a' seria diminuído em 2 a cada repetição. Caso 'a' fosse menor que 9, o bloco não seria executado.

Page 46: Python BGE

Lógica de programação

Lembra deste exemplo?

faça (Subir numa cadeira/escada para alcançar o bocal);Se (não alcançar) então faça (procurar um objeto mais alto para subir);Fim Se;

Por que a palavra "faça" não está destacada? Simples, porque ela não é reservada. No exemplo acima, "faça" é uma função separada criada por nós. Como?

Page 47: Python BGE

Lógica de programação

Inicio AlgoritmoInteiro Função somaInteiros (Inteiro a, Inteiro b) Retorne a + b;Fim Função

Inteiro x = 2;Inteiro y = 7;Escreva (somaInteiros (x, y) - 3);Fim Algoritmo

Vamos analisar passo a passo...

Page 48: Python BGE

Lógica de programação

Inteiro Função somaInteiros (Inteiro a, Inteiro b) Retorne a + b;Fim Função

Esse trecho cria uma função chamada 'somaInteiros' que usa dois parâmetros de entrada: 'a' e 'b', ambos variáveis do tipo Inteiro. Note que a mesma regra para os nomes de variáveis também vale para nomes de funções.

Essa função devolve a soma de 'a' com 'b' através do comando Retorne. Uma vez que a própria função é do tipo Inteiro, seu retorno deve ser do mesmo tipo.

Page 49: Python BGE

Lógica de programação

Inteiro x = 2;Inteiro y = 7;Escreva (somaInteiros (x, y) - 3);

Mais adiante, criamos duas variáveis do tipo Inteiro ('x' e 'y') e as usamos como parâmetros para a nossa função recém criada.

Finalmente, o resultado da função (2 + 7 = 9) é subtraido em 3, ou seja, nosso resultado final é 6.

Vamos ver outro exemplo com a função somaInteiros...

Page 50: Python BGE

Lógica de programação

Escreva (somaInteiros (2, 6) - 1.65);

Aqui estamos passando os números 2 e 6 para a nossa função e subtraindo 1.65 do resultado.

Entretanto, isso não funcionaria, pois a nossa função é do tipo Inteiro e estamos tentando subtrair um número do tipo Decimal do retorno dela.

Quando falamos em 2, 6 e 1.65, estamos na verdade falando de literais, ou seja, valores puros que não tem vínculo com nenhuma variável.

Page 51: Python BGE

Lógica de programação

Logo, o correto seria:

Inicio AlgoritmoDecimal Função somaInteiros (Decimal a, Decimal b) Retorne a + b;Fim Função

Escreva (somaInteiros (2.0, 6.0) - 1.65);Fim Algoritmo

Page 52: Python BGE

Lógica de programação

Um conceito importante a se aprender é o de vetores. Um vetor nada mais é do que uma variável com capacidade de armazenar vários valores diferentes, por exeplo:

Caractere Vetor a = ['a', 'b', 'c', 'd'];

Aqui criamos um vetor chamado 'a', do tipo Caractere contendo os valores 'a', 'b', 'c' e 'd'.

Page 53: Python BGE

Lógica de programação

Para acessar um valor dentro de um vetor, usa-se a seguinte sintaxe:

Escreva (a[0]);

O sinal de chaves na referência da variável indica que estamos acessando uma das posições do vetor, no caso a posição 0 (a primeira). A maioria das linguagens de programação adota a posição 0 como sendo a primeira posição de um vetor. Portanto, os valores do nosso vetor e seus índices seriam:

0='a', 1='b', 2='c', 3='d'

Page 54: Python BGE

Lógica de programação

Juntando tudo que aprendemos, já temos condições de criar algoritmos bem complexos.

Pensemos numa calculadora. Vamos abstrair a forma que ela funciona. Podemos usar funções para as operações básicas (soma, subtração, multiplicação e divisão).

Também podemos criar um loop que irá se repetir enquanto o valor informado pelo usuário no "menu" for diferente de 1, 2, 3 ou 4, sendo que cada número corresponde a uma operação.

Page 55: Python BGE

Lógica de programação

Início AlgoritmoDecimal Função soma (Decimal a, Decimal b) Retorne a + b;Fim Função

Decimal Função subtrai (Decimal a, Decimal b) Retorne a - b;Fim Função

Decimal Função multiplica (Decimal a, Decimal b) Retorne a * b;Fim Função

continua...

Page 56: Python BGE

Lógica de programação

Decimal Função divide (Decimal a, Decimal b) Retorne a / b;Fim Função

Decimal a = 0.0;Decimal b = 0.0;Inteiro opcao = 0;

Enquanto (opcao == 1 ou opcao == 2 ou opcao == 3 ou opcao == 4) faça Escreva ("Escolha a operação:"); Escreva ("1 - Soma"); Escreva ("2 - Subtração"); continua...

Page 57: Python BGE

Lógica de programação

Escreva ("3 - Multiplicação"); Escreva ("4 - Divisão");

Leia (operacao); Escreva ("Informe o primeiro número: "); Leia (a); Escreva ("Informe o segundo número: "); Leia (b);

Se (operacao == 1) então Escreva ("Resultado: ", soma (a, b)); Fim Se

continua...

Page 58: Python BGE

Lógica de programação

Senão Se (operacao == 2) então Escreva ("Resutado: ", subtrai (a, b)); Fim Senão Se Senão Se (operacao == 3) então Escreva ("Resultado: ", multiplica (a, b)); Fim Senao Se Senão Se (operacao == 4) então Escreva ("Resutado: ", divide (a, b)); Fim Senão SeFim EnquantoFim Algoritmo

Page 59: Python BGE

Lógica de programação

Mas e como fica a divisão por zero? Basta alterar o trecho que trata a operação número 4:

Senão Se (operacao == 4) então Se (b == 0) então Escreva ("Não é possível dividir um número por zero!"); Fim Se Senão Escreva ("Resutado: ", divide (a, b)); Fim SenãoFim Senão Se

Page 60: Python BGE

Lógica de programação

Algoritmos podem ser meio confusos a primeira vista, mas são uma parte essencial no aprendizado da programação, portanto não desista de tentar entendê-los!

Se você conseguiu chegar até entendendo tudo, ótimo! Você está um passo (e muito importante) mais perto de aprender a programar, seja em Python, Java, C++, ou o que for.

Todas as linguagens de programação tem seu funcionamento baseado nos algoritmos, ou seja, um código-fonte nada mais é do que um algoritmo "traduzido" para uma linguagem.

Page 61: Python BGE

Orientação a Objetos

A Orientação a Objetos (OO) foi criada para aproximar o mundo real do mundo da programação.

Na OO, o desenvolvedor "molda" um "universo" a partir de suas abstrações.

Você lembra o que são abstrações, não é?

Page 62: Python BGE

Orientação a Objetos

Recapitulando: abstração é a definição de uma pessoa para um determinado tema. Por exemplo, uma abstração para carro:

Todo carro tem: marca, modelo, cor, ano de fabricação, tipo de combustível e chassi. (Paramos por aqui)Todo carro: liga, desliga, acelera, freia e troca de marchas.

Pode ser que a sua definição de carro seja um pouco diferente da minha. Isso não quer dizer necessariamente que esteja errada.

Page 63: Python BGE

Orientação a Objetos

Logo, se todo carro tem as características que enumeramos, podemos considerar "Carro" como uma classe (grupo).

Uma classe é uma definição de um tipo de objeto, por exemplo: um Ford Focus é um objeto da classe Carro, logo seu tipo de dado é Carro.

A OO nos permite criar nossos próprios tipos de dados. Além do Inteiro, Decimal, etc. também é possível incluir o Carro, caso seja necessário para o nosso problema.

Carro, Pessoa, Animal, Computador... não importa! Basta criar a classe para que ela possa ser utilizada com um tipo de dado.

Page 64: Python BGE

Orientação a Objetos

Uma classe contém atributos e métodos. Atributos são as características (cor, modelo, etc.), enquanto que os métodos são as operações (ligar, trocar de marchas, etc.).

Além disso, uma classe também contém um construtor, ou seja, um método especial (reservado) que é responsável por inicializar a classe e seus atributos.

O construtor recebe os parâmetros necessários para a correta instanciação (inicialização) de um objeto de uma classe qualquer.

Page 65: Python BGE

Orientação a Objetos

Nossa classe Carro ficaria assim:

Classe Carro Caractere marca; Caractere modelo; Caractere cor; Inteiro ano; Caractere combustivel; Caractere chassi; Lógico ligado = Falso;

continua...

Page 66: Python BGE

Orientação a Objetos

Construa Carro (Caractere mar, Caractere mod, Caractere c, Inteiro a, Caractere com, Caractere cha) marca = mar; modelo = mod; cor = c; ano = a; combustivel = com; chassi = cha; Fim Construa

Lógico Função liga () ligado = Verdadeiro Fim FunçãoFim Classe

Page 67: Python BGE

Orientação a Objetos

Note que os atributos da classe são representados como variáveis, enquanto que os métodos são representados como funções. Note que o construtor também é uma função e que criei apenas a função 'liga' no exemplo para não ficar muito grande.

Notou que as variáveis foram declaradas sem um valor atribuído a elas? Isso foi feito porque a tarefa de dar um valor às variáveis é trabalho do construtor.

No momento em que criamos um objeto da classe Carro, o construtor é executado. Logo, devemos criar nosso objeto passando os valores que queremos e o construtor irá atribuir esses valores às variáveis correspondentes.

Page 68: Python BGE

Orientação a Objetos

Isso acontece da seguinte maneira:

Carro fordFocus = Carro ('Ford', 'Focus', 'azul', 2007, 'gasolina', '879876567');

Quando esse trecho é executado, o construtor da classe Carro é disparado atribuindo os valores que passamos e então nosso objeto é criado e armazenado a variável 'fordFocus', do tipo Carro.

Page 69: Python BGE

Orientação a Objetos

O que acontece se quisermos alterar a cor do nosso objeto 'fordFocus'? Simplesmente podemos acessar a variável 'cor' e redefinir seu valor. Isso é feito através de um sinal de ponto:

fordFocus.cor = 'vermelho';

O mesmo vale para as outras variáveis. O símbolo do ponto diz que a variável cor que queremos mudar é do nosso 'fordFocus'.

Basicamente, o ponto nos dá acesso aos atributos e métodos de uma classe.

Page 70: Python BGE

Orientação a Objetos

Lembre-se que a variável 'ligado' é inicializada como Falso. Se quisermos ligar o carro, podemos tanto alterar diretamente o valor da propriedade 'ligado', quando utilizar a função 'liga':

fordFocus.ligado = Verdadeiro;fordFocus.liga();

Page 71: Python BGE

Orientação a Objetos

A OO nos dá ferramentas para organizar melhor nosso trabalho, de forma que um erro acontecer em alguma parte do algoritmo, fica fácil de corrigí-lo, bastando alterar apenas aquela parte específica em vez do algoritmo todo.

O Python é uma linguagem orientada a objetos, assim como os módulos da BGE estão também foram desenvolvidos usando a OO, portanto é bom que entenda bem os conceitos antes de continuar.

Ainda há muito mais para se aprender sobre algoritmos e OO, porém vou deixar isso a seu critério. Se você entendeu tudo até aqui, então está já pronto para o Python.

Page 72: Python BGE

PythonAgora as coisas começam a ficar interessantes! Recomendo que tenha entendido bem a parte de algoritmos antes de continuar. Embora não seja obrigatório, irá facilitar muito a sua vida.

Python é uma linguagem de programação de alto nível, ou seja, é bem próxima a linguagem natural (humana). Portanto, escrever um código em Python é quase a mesma coisa que escrever um algoritmo. As diferenças são muito poucas.

Page 73: Python BGE

Python

Python também é uma linguagem interpretada, ou seja, para rodar um programa em Python, é necessário ter o interpretador do Python instalado no sistema ou embutido em sua aplicação.

Uma coisa importante a esclarecer é que Python não gera executáveis (.exe) nativamente. Isso se dá pelo fato de que ele é uma linguagem de scripts. Existem formas de se gerar executáveis, mas esse assunto não será abordado neste curso.

Page 74: Python BGE

Python

Antes de continuar, preciso que você instale o Python em seu sistema. Ele pode ser baixado aqui: http://www.python.org/

Se tudo deu certo, se você for ao menu Iniciar - Executar, digitar "python" e clicar em ok deverá ver esta janela:

Page 75: Python BGE

Python

Caso tenha recebido alguma mensagem de erro, clique com o botão direito do mouse em “Meu computador”, e depois em “propriedades”. Clique na guia “avançado” e clique em “variáveis de ambiente”. Na janela “Variáveis de sistema” escolha a variável "path" e clique em "editar". Agora acrescente o endereço do interpretador nesta variável antecedido por um ponto e virgula “;”.

Page 76: Python BGE

Python

Muito bem, com tudo pronto podemos começar a brincar com o interpretador. As frases depois do caractere "#" são comentários, ou seja, não farão nada no código.Tente os seguintes comandos (tecle Enter no final de cada um):

2 + 2 #Aqui o retorno é 42 == 2 #Aqui o retorno é True (Verdadeiro)2 != 2 #Aqui o retorno é False (Falso) a = 2 #Sem retornoa #Aqui o retorno é 2a + 2 #Aqui o retorno é 4a #Aqui o retorno é 2 (a não foi somado)a = a + 2 #Sem retorno (a foi somado)a #Aqui o retorno é 4a += 2 #Sem retorno (equivale a: a = a + 2)a #Aqui o retorno é 6

Page 77: Python BGE

Python

Como você pode ver, conforme vamos digitando os comandos, vamos obtendo as respostas logo em seguida. Notou que o Python não usa pronto e vírgula no fim das instruções? Você deve ter notado também que o modo de trabalhar com variáveis é um pouco diferente do que aprendemos nos algoritmos.

Não precisamos informar o tipo da variável antes da sua declaração (nome), pois a linguagem se encarrega de descobrir o tipo automaticamente para nós baseando-se no valor atribuído à variável. Isso é chamado de tipagem dinâmica.

Page 78: Python BGE

Python

Com o conceito de tipagem em mente, deve-se saber que as variáveis podem ter seu tipo alterado ao decorrer do código, por exemplo:

a = 2 #Sem retorno a #Retorno: 2 a = 2.4 #Sem retornoa #Retorno: 2.4a = 'bla bla bla' #Sem retornoa #Retorno: 'bla bla bla'

Portanto, bastante atenção na hora de usar as variáveis. Não tente fazer algo como 'a +2', se 'a' estiver com o valor 'bla bla bla' ou você verá uma bela mensagem de erro.

Page 79: Python BGE

Python

Também é possível converter variáves:

a = '3' #definimos a como um Caractere ('3')a = int (a) #redefinimos a convertendo-o para Inteiroa = str(a) #convertemos novamente para Caractere

Os tipos de dados suportados pelo Python que mais iremos utilizar são: 'int' (Inteiro), 'float' (Decimal), 'long' (Inteiro longo), 'str' (Caractere) e 'list' (lista).

Existe o Inteiro longo, pois o 'int' só suporta um determinado número de dígitos, logo se você tiver um número muito grande, ele deve ser do tipo 'long'.

Page 80: Python BGE

Python

Já a lista, é o próprio Vetor, porém ela contém métodos para que se possa, entre outras coisa, adicionar, remover, dividir e ordenar os dados contidos nela. Por exemplo:

lista = ['a', 'g'] #criamos um Vetor de caractereslista.append ('f') #adicionamos o 'f' ao fim do vetorlista.sort () #ordenamos o vetor ['a', 'f', 'g']lista.remove ('a') #removemos o 'a' do vetor

Portanto, daqui pra frente quando falarmos em vetores, estaremos falando de algoritmos e quando falarmos em listas, estaremos falando de Python.

Page 81: Python BGE

Python

O modo como o Python trata as condições é a seguinte:

if a > 10: #if é o Se dos algoritmos print a, ' é maior que 10' #print é o Escrevaelif a < 10 : #elif é o Senao Se print a, ' é menor que 10'else: #else é o Senao print a, ' é igual a 10'

Mais algumas diferenças a observar:'elif' é a abreviação de 'else if' (Senão Se)'print' não imprime algo na impressora, mas sim na tela. É o mesmo que o Escreva nos algoritmosNem o 'if' (e variantes), nem o 'print' precisam de parênteses (Porém Python 3.0 e superiores precisam de parenteses)

Page 82: Python BGE

Python

É possível escrever várias linhas com um único print usando-se três aspas no começo e no fim da instrução:

print """Primeira linhaSegunda linhaTerceira linha""" Também é possível usar os caracteres \n para quebra de linha: print """Primeira linha\n Segunda linha\n Terceira linha"""

Page 83: Python BGE

Python

Outra coisa importante a se notar é que os blocos não possuem uma demarcação de Inicio e Fim como nos algoritmos. Ao invés disso, o Python usa um sinal de dois pontos para demarcar o início de um bloco. Todo o código dentro dele deve estar com uma tabulação (4 espaços) a mais que a linha inicial.

O Python entende que um bloco termina, quando a tabulação diminui, ou seja, quando é igual ao da primeira linha.

if a > 10: #dois pontos = Inicio print a, 'é maior que 10' #+1 tabulação = blocoelse: #-1 tabulação = Fim print a, 'não é maior que 10'

Page 84: Python BGE

Python

Para fazer um Leia em Python, usa-se a função 'raw_input':

a = raw_input() #Ficará esperando uma entrada no tecladoprint a #Mostrará o valor passado para 'a'

O Python diferencia funções de variáveis pelos parênteses. Como raw_input é uma função, temos que colocar os sinais de abre e fecha parênteses.

Não há nada dentro dos parênteses porque não informamos nenhum parâmetro à função.

Page 85: Python BGE

Python

Eis um exemplo de função com parâmetros:

def soma (a, b): #define-se a função 'soma' return a + b #seu retorno é a soma dos parametros

soma (2, 3) #usa-se a função para somar 2 e 3

A palavra 'def' é a abreviação de 'define' (defina), ou Função, no caso dos algoritmos. Novamente não é preciso informar o tipo de dados, pois ele é definido automaticamente através do comando 'return' (Retorne).

Page 86: Python BGE

Python

Os operadores do Python são os mesmos utilizados nos algoritmos. Recapitulando:

Atribuição (a = 10): atribui um valor a uma variávelIgualdade (a == 10): compara se dois valores são iguaisMaior (a > 10): compara se um valor é maior que outroMenor (a < 10): compara se um valor é menor que outroMaior ou igual (a >= 10): compara se um valor é maior ou igual a outroMenor ou igual (a <= 10): compara se um valor é menor ou igual a outroDiferença (a != 10): compara se um valor é diferente do outro.

Page 87: Python BGE

Python

A estrutura Enquanto/faça dos algoritmos em Python é a seguinte:

a = 10 #criamos a variavel 'a' com valor 10

while a != 0: #enquanto 'a' for diferente de zero a -= 1 #diminui-se um do valor de 'a' print a #mostra o valor na tela

A diferença aqui é que o 'while' (Enquanto) não precisa de um faça. Como as demais estruturas, ela também não requer parênteses.

Page 88: Python BGE

Python

A estrutura Repita/até que não existe em Python. Uma vez que é idêntica ao Enquanto/faça. Entretanto, a estrutura Para/faça existe, uma vez que seu funcionamento é diferente do Repita/até que:

for i in range (1, 10): print i

Aqui temos um 'for' (Para) que está trabalhando em cima de uma variável 'i' num intervalo de 1 a 10 (função 'range'). A cada repetição, o valor da variável é mostrado na tela.

Page 89: Python BGE

Python

A função 'range' cria um intervalo completo de valores, ou seja, um Vetor. No caso do exemplo: [1, 2, 3, 4, 5, 6, 7, 8, 9]

Porque vai até 9 e não até 10? Porque a função range tem seu primeiro parâmetro inclusivo e o segundo exclusivo, ou seja, o valor informado no primeiro parâmetro é incluído no vetor e o segundo não.

Se a idéia era criar uma lista de 10 posições, então poderíamos usar simplesmente:

range (10)

Page 90: Python BGE

Python

O funcionamento da esturura 'for' é basicamente a seguinte:

É necessária uma variável (no exemplo, 'i')É necessário um intervalo de valores para determinar o número de repetições.A palavra 'in' é uma estrutura condicional, ou seja, retorna Verdadeiro (True) ou Falso (False)Logo, o 'for' testa a cada repetição se o valor da variável está dentro do intervalo definido. Se estiver, o retorno é verdadeiro, 'i' recebe o valor da posição atual da lista e a repetição continuaCaso seja falso, a repetição acaba

Page 91: Python BGE

Python

Você pode testar a condição 'in':

vetor = [1, 5, 7, 6]#vetores também não precisam de tipoa = 2 a in vetor #testa se 'a' está dentro do vetora = 5a in vetor

Também é possível usar o 'in' dentro de um 'if', por exemplo:

if a in vetor: print a, ' está dentro do vetor'

Page 92: Python BGE

Python

Lembra do algoritmo da nossa calculadora? Hora de dar vida a ela. Crie um arquivo chamado "calculadora.py" e escreva o seguinte:

def soma (a, b): return a + b

def subtrai (a, b): return a - b

def multiplica (a, b): return a * b;

def divide (a, b): return a / b; continua...

Page 93: Python BGE

Python

a = 0.0b = 0.0operacao = 1

while (operacao in [1, 2, 3, 4]): print """Escolha uma operacao:'1 - Soma'2 - Subtracao'3 - Multiplicacao'4 - Divisao""" operacao = int (raw_input())

print 'Informe o primeiro numero: ' a = float (raw_input()) print 'Informe o segundo numero: ' b = float (raw_input()) continua...

Page 94: Python BGE

Python

if operacao == 1: print 'Resultado: ', soma (a, b) elif operacao == 2:print 'Resultado: ', subtrai (a, b)elif operacao == 3:print 'Resultado: ', multiplica (a, b)elif operacao == 4:if b == 0:print 'Não é possível dividir um número por zero'else :print 'Resultado: ', divide (a, b)

Execute esse script dando um clique duplo em cima dele. Caso não consiga, associe o Python como programa padrão para arquivos .py

Page 95: Python BGE

Python

Aqui um exemplo de uma classe em Python:

class Humano: nome = None idade = None sexo = None altura = None peso = None def __init__(self, novoNome, novaIdade, novoSexo, novaAltura, novoPeso): self.nome = novoNome self.idade = novaIdade self.sexo = novoSexo self.altura = novaAltura self.peso = novoPeso continua...

Page 96: Python BGE

Python

def mostraDados(self): print 'Nome: ' + self.nome print 'Idade: ' + str(self.idade) print 'Sexo: ' + self.sexo print 'Altura: ' + str(self.altura) print 'Peso: ' + str(self.peso) humano1 = Humano('Fulano', 32, 'M', 1.82, 68) humano2 = Humano('Ciclana', 22, 'F', 1.67, 58) humano1.mostraDados() humano2.mostraDados()

Page 97: Python BGE

Python

Partindo do princípio, temos a criação da classe ('class') e seus atributos:

class Humano: nome = None idade = None sexo = None altura = None peso = None

O termo 'None' (necessário letra maiúscula) se refere a um valor em branco, ou seja, nossas variáveis não tem valor algum atribuído a elas.

Page 98: Python BGE

Python

Em seguida temos o construtor:

def __init__(self, novoNome, novaIdade, novoSexo, novaAltura, novoPeso): self.nome = novoNome self.idade = novaIdade self.sexo = novoSexo self.altura = novaAltura self.peso = novoPeso

Como o construtor é uma função, deve-se usar o 'def'. O termo '__init__' (abreviação de initialize, ou inicialize) é o termo reservado no Python para construtores.

Page 99: Python BGE

Python

O termo 'self', refere-se à própria classe, ou seja, se nosso construtor fosse assim ele nao iria funcionar:

def __init__(self, nome, idade, sexo, altura, peso): nome = nome idade = idade sexo = sexo altura = altura peso = peso

Page 100: Python BGE

Python

O que aconteceria é que as variáveis da classe não receberiam valor algum! A instrução abaixo iria apenas substituir o valor da variável nome com o próprio valor que já está atribuído a ela:

nome = nome

Para entender isso, precisamos entender o conceito de variável local e global.

Page 101: Python BGE

Python

Uma variável local é aquela que só é acessível dentro do próprio bloco onde ela se encontra, enquanto que uma variável local é acessível de qualquer lugar do código (após sua criação). Um exemplo:

nome = 'Meu nome'

def trocaNome (novoNome): nome = novoNome

print novoNomeprint nome

Aqui teríamos um erro, pois estaríamos tentando acessar uma variável que não existe mais.

Page 102: Python BGE

Python

A fim de economizar memória e processamento, assim que uma função termina de ser executada, as variáveis locais dela são apagadas.

Por isso não conseguimos mostrar o valor da variável 'novoNome' fora da função 'trocaNome'. Entretanto, o valor da variável 'nome' é mostrado pois ela ainda existe.

Uma regra simples para variáveis locais é: variáveis somente são acessíveis enquanto a identação for a mesma. Ou seja, se uma instrução com identação menor tentar acessar uma variável que está com identação maior, irá ocorrer um erro.

Page 103: Python BGE

Python

A regra para variáveis globais é: variáveis com identação menor são acessíveis para instruções com identação maior.

Portanto, como no exemplo da classe Humano temos duas variáveis com o mesmo nome, devemos dizer ao construtor que o valor que queremos atribuir é para a variável 'nome' da classe, e não o parâmetro 'nome'. Isso é feito usando a palavra 'self' (si próprio).

def __init__(self, nome, idade, sexo, altura, peso): self.nome = nome

Page 104: Python BGE

Python

Note também que existe uma palavra 'self' como primeiro parâmetro do construtor. Isso é uma regra do Python que diz que toda função dentro de uma classe deve começar com a palavra 'self', incluindo o construtor. Por isso, o método 'mostraDados' da classe também tem esse parâmetro:

def mostraDados(self): print 'Nome: ' + self.nome print 'Idade: ' + str(self.idade) print 'Sexo: ' + self.sexo print 'Altura: ' + str(self.altura) print 'Peso: ' + str(self.peso)

Page 105: Python BGE

Python

Ao final do exemplo, criamos dois objetos da classe Humano e chamamos a função 'mostraDados' de cada um.

humano1 = Humano('Fulano', 32, 'M', 1.82, 68) humano2 = Humano('Ciclana', 22, 'F', 1.67, 58) humano1.mostraDados() humano2.mostraDados()

Tente executar esse exemplo (usando o código completo) para ver como ele funciona e qual é o retorno final.

Page 106: Python BGE

Python

Tente executar esse trecho de código no interpretador do Python (linha de comando):

import datetimeprint datetime.datetime.now()

Seu retorno deve ser o dia e a hora atuais. O comando 'import' diz ao Python para carregar um módulo. Somente depois que um módulo é carregado é que podemos utilizá-lo.

O módulo 'datetime' é responsável por funções de hora e data no Python.

Page 107: Python BGE

Python

Um módulo, nada mais é do que uma pasta de arquivos contendo um arquivo chamado "__init__.py" dentro dela. Como você deve lembrar a palavra '__init__' é usada para inicializar classes, mas também serve para dizer ao Python que uma pasta é um módulo.

Como você deve imaginar, esse arquivo também é responsável por inicializar o módulo. Além dele, a pasta também deve conter pelo menos um outro arquivo com extensão ".py" qualquer.

Esse arquivo é o módulo em si, ou seja, deve conter variáveis, funções, classes, etc. a fim de realizar uma tarefa.

Page 108: Python BGE

Python

Você pode criar um módulo chamado "minhasFuncoes". Para isso, basta criar uma pasta com esse mesmo nome, dentro dela criar um arquivo chamado "__init__.py".

Dentro desse arquivo, coloque apenas:

from minhasFuncoes import *

Isso diz ao Python para importar tudo ('*') de dentro ('from') do arquivo 'minhasFuncoes'. Ainda dentro da pasta crie o arquivo "minhasFuncoes.py".

Page 109: Python BGE

Python

Dentro do novo arquivo, coloque isso:

def funcao1(): print 'Primeira funcao'

def funcao2(): print 'Segunda funcao'

Fora da pasta minhasFuncoes, crie um arquivo com qualquer nome, como "teste.py", por exemplo. Dentro dele coloque:

import minhasFuncoes

minhasFuncoes.funcao1()raw_input()

Page 110: Python BGE

Python

Ao executar o arquivo "teste.py", devemos receber a mensagem "Primeira funcao" como saída. Como o Python fecha a tela do console assim que a execução termina, colocamos um 'raw_input' no fim do arquivo para que o interpretador fique esperando uma entrada no teclado. Isso nos dá tempo de ver a mensagem.

O que fizemos foi importar o módulo 'minhasFuncoes' e chamar a função 'funcao1' desse módulo. Note que módulos também podem ser locais e globais e o que fizemos foi criar um módulo local.

Page 111: Python BGE

Python

Se você executar o console do Pyhton e tentar importar seu módulo recém criado, deverá receber uma mensagem de erro.

Page 112: Python BGE

Python

Isso acontece porque nosso módulo não é global. Para torná-lo global, precisamos colocá-lo na pasta "Lib" que se econtra dentro da pasta de instalação do Python.

Depois de fazer isso, podemos executar o interpretador novamente e tentar fazer a importação. Nesse caso, não iremos receber mensagem de erro, o que significa que o módulo foi importado corretamente.

Page 113: Python BGE

Python

Page 114: Python BGE

Python

Ao fazer importações, é possível dar um "apelido" (alias) aos módulos, como por exemplo:

import datetime as dtprint dt.datetime.now()

Nesse caso, importamos o módulo 'datetime' como 'dt'. Quando usamos o apelido, o Python sabe que estamos na verdade falando do módulo.

Page 115: Python BGE

Python

Para finalizar, devo lhe apresentar um conceito muito útil:

def igualADez (numero): if numero == 10: return True return False

numero = 5resultado = igualADez (numero)if (resultado): print numero, ' é igual a 10'else: print numero, ' é diferente de 10'

Page 116: Python BGE

Python

No exemplo criamos uma função que testa se um número é igual a 10 e retorna Verdadeiro ou Falso. Na primeira linha da função, temos a comparação do número com 10. Se for verdadeira, a função irá retornar 'True'.

É importante dizer que assim que o 'return' é executado, a função termina, pois já se tem um resultado. Portanto a função só irá retornar 'False' quando a condição não for verdadeira.

Page 117: Python BGE

Python

Em seguida, temos a criação da variável global 'numero' (diferente do parâmetro 'numero') e lhe atribuímos o valor 5.

Em seguida criamos a variável 'resultado' que recebe o retorno da função 'igualADez' e lhe passa a variável 'numero' como parâmetro. Logo, o valor da variável 'resultado' nesse caso seria 'False' e ela seria do tipo boolean (Lógico).

Page 118: Python BGE

Python

No final do código temos uma condição meio estranha. Como assim "if resultado"?

Como você deve lembrar, o bloco 'if' só é executado se sua condição for verdadeira. Isso pode ser conseguido tanto com uma comparação (a maior que b, por exemplo) como usando diretamente um valor Verdadeiro (True).

No exemplo, o valor de 'resultado' é False, portanto o bloco 'else' será executado.

Page 119: Python BGE

Python

Uma outra forma de fazer a mesma coisa e economizar algumas linhas seria:

if (igualADez(5)): print '5 é igual a 10'else: print '5 é diferente de 10'

Como a função 'igualADez' retorna apenas True ou False, é tudo que precisamos para poder usá-la como parâmetro no nosso 'if'.

Page 120: Python BGE

Python

Eis uma agenda simples:

#-*- coding: utf-8 -*-class Contato:codigo = Nonenome = Nonetelefone = None

def __init__(self, novoCodigo, novoNome, novoTelefone):self.codigo = novoCodigoself.nome = novoNomeself.telefone = novoTelefone

continua...

Page 121: Python BGE

Python

contatos = []op = 0

while op != 5:print u'Escolha uma opção:'print '1- Visualizar contatos'print '2- Adicionar contato'print '3- Editar contato'print '4- Remover contato'print '5- Sair'

try:op = int(raw_input())except:print u'Esolha uma opção de 1 a 5'raw_input()

continua...

Page 122: Python BGE

Python

if op == 1:for contato in contatos:print u'Código: ', contato.codigoprint 'Nome: ', contato.nomeprint 'Telefone: ', contato.telefoneprint '\n'elif op == 2:print u'Código: 'codigo = raw_input()for contato in contatos:if contato.codigo == codigo: print u'Esse código já existe' breakprint 'Nome: 'nome = raw_input()print 'Telefone: 'telefone = raw_input()contatos.append(Contato(codigo, nome, telefone))

continua...

Page 123: Python BGE

Python

elif op == 3:print u'Código: 'codigo = raw_input()for contato in contatos:if contato.codigo == codigo:print u'Novo código: 'contato.codigo = raw_input()print 'Novo nome: 'contato.nome = raw_input()print 'Novo telefone: 'contato.telefone = raw_input()break

continua...

Page 124: Python BGE

Python

elif op == 4:print u'Código: 'codigo = raw_input()for contato in contatos:if contato.codigo == codigo:contatos.remove(contato)print 'Contato removido!'break

Esse código deve ser capaz de mostrar os contatos (código, nome e telefone), adicionar um novo contato, editar um contato existente e remover um contato.

Vamos analisá-lo por partes

Page 125: Python BGE

Python

#-*- coding: utf-8 -*-class Contato:codigo = Nonenome = Nonetelefone = None

def __init__(self, novoCodigo, novoNome, novoTelefone):self.codigo = novoCodigoself.nome = novoNomeself.telefone = novoTelefone

Nenhuma surpresa aqui, exceto pela primeira linha. Ela nos diz que a codificação do nosso arquivo .py é UTF-8, ou seja, que queremos ser capazes de mostrar acentos e outros caracteres especiais nas nossas mensagens.

Page 126: Python BGE

Python

Para que isso funcione, é preciso configurar nosso editor para trabalhar com UTF-8. No caso do Notepad++ (o que eu recomendo), isso pode ser feito no menu Formatar - Codificação UTF-8.

Page 127: Python BGE

Python

contatos = []op = 0

while op != 5:print u'Escolha uma opção:'print '1- Visualizar contatos'print '2- Adicionar contato'print '3- Editar contato'print '4- Remover contato'print '5- Sair'

try:op = int(raw_input())except:print u'Esolha uma opção de 1 a 5'raw_input()

Aqui criamos uma lista vazia onde serão guardados os contatos. Também mostramos as opções e a lemos.

Page 128: Python BGE

Python

try:op = int(raw_input())except:print u'Esolha uma opção de 1 a 5'raw_input()

Usamos o 'try' (tente) quando alguma parte do nosso código pode gerar algum erro e o programa ser simplesmente finalizado por isso.

O 'except' (exceto) é o que deve ser executado caso o 'try' falhe. Se digitássemos letras ao invés de números, isso faria o casting (conversão para inteiro do 'raw_input') dar erro e então o 'except' seria executado

Page 129: Python BGE

Python

if op == 1:for contato in contatos:print u'Código: ', contato.codigoprint 'Nome: ', contato.nomeprint 'Telefone: ', contato.telefoneprint '\n'

Aqui tratamos da opção número 1 (visualizar contatos) selecionando cada item (contato) dentro da lista (contatos) e mostrando seu respectivo código, nome e telefone.

O 'u' antes de uma string, significa que ela deve ser convertida para Unicode. Assim os caracteres especiais e de acentuação aparecem corretamente. O '\n' é um caractere especial que serve para pular uma linha.

Page 130: Python BGE

Python

elif op == 2:print u'Código: 'codigo = raw_input()for contato in contatos:if contato.codigo == codigo: print u'Esse código já existe' breakprint 'Nome: 'nome = raw_input()print 'Telefone: 'telefone = raw_input()contatos.append(Contato(codigo, nome, telefone))

A opção 2 não muda muito. Aqui lemos um código, buscamos na lista para ver se ele já existe e então gravamos os novos dados na lista. O comando 'break' serve para interromper a repetição de um laço ('while', 'for').

Page 131: Python BGE

Python

elif op == 3:print u'Código: 'codigo = raw_input()for contato in contatos:if contato.codigo == codigo:print u'Novo código: 'contato.codigo = raw_input()print 'Novo nome: 'contato.nome = raw_input()print 'Novo telefone: 'contato.telefone = raw_input()break

Aqui procuramos o contato com o código informado e, assim que o acharmos, gravamos os novos dados por cima dos antigos e interrompemos a repetição ('break').

Page 132: Python BGE

Python

elif op == 4:print u'Código: 'codigo = raw_input()for contato in contatos:if contato.codigo == codigo:contatos.remove(contato)print 'Contato removido!'break

Aqui buscamos na lista pelo contato com o código informado, o removemos dela e interrompemos a repetição.

Quanto interrompemos a repetição, o 'break' nos leva para fora do bloco.

Page 133: Python BGE

Python

Muito bem, mas esse tipo de informação é valiosa e acredito que você não gostaria de perder seus dados assim que o programa for fechado não é?

É necessário um jeito de fazer com que os dados fiquem gravados mesmo que o programa seja fechado e o computador seja desligado.

Podemos fazer isso com arquivos ou com banco de dados e irei mostrar os dois jeitos. Teremos um capítulo todo sobre banco de dados mais adiante, então vamos nos concentrar na idéia dos arquivos.

Page 134: Python BGE

Python

O Python tem a função 'open', que retorna um objeto do tipo File (arquivo). Esse objeto possui funções para ler arquivos, bem como gravar dados dentro deles.

A primeira mudança que faremos no nosso código da agenda é acrescentar a variável 'CAMINHOARQUIVO' ao início do código:

#-*- coding: utf-8 -*-import osCAMINHOARQUIVO = os.path.dirname(os.path.abspath(__file__)) + '\\agenda.txt'

Page 135: Python BGE

Python

Para que o código funcione, é necessário criar o arquivo "agenda.txt" na mesma pasta em que se encontra o arquivo "agenda.py".

Page 136: Python BGE

Python

O que fizemos foi importar o módulo 'os' (Operating System) que possui funções específicas para cada sistema operacional.

Depois disso, criamos uma variável ('CAMINHOARQUIVO') que basicamente pega o caminho completo do arquivo "agenda.py".

Com o caminho em mãos, adicionamos mais uma barra e o nome do nosso arquivo. É necessário usar duas barras, pois a barra identifica um caractere específico (lembra do '\n'?), logo quando escrevemos '\\' o retorno será apenas uma barra.

Page 137: Python BGE

Python

Agora vamos precisar ler o conteúdo do arquivo e convertê-lo em objetos da nossa classe Contato. Entretando, não temos como fazer isso porque o arquivo "agenda.txt" está vazio.

Outra coisa que nos impede é que ainda não criamos um padrão de formatação para o arquivo, então vamos estabelecer assim:

[codigo]1[nome]Fulano de Tal[telefone](44) 4444-4444

O que estiver depois do símbolo de fechamento de chave (']') é o que queremos.

Page 138: Python BGE

Python

Portanto, vamos inserir alguns contatos nesse formato no nosso arquivo "agenda.txt":

Não se esqueça de salvar esse arquivo no formato UTF-8 tambem!

Page 139: Python BGE

Python

Agora que temos nosso padrão e alguns dados, vamos adicionar a função que lê os dados do arquivo:

contatos = []op = 0

for linha in open (CAMINHOARQUIVO):split = linha.split(']')novoContato = Contato(None, None, None)

for item in split:novoItem = item.replace('[codigo', '').replace('[nome', '')novoItem = novoItem.replace('[telefone', '').replace('\n', '')novoItem = novoItem.replace('\xef\xbb\xbf', '')if split.index(item) == 1:novoContato.codigo = novoItemelif split.index(item) == 2:novoContato.nome = novoItemelif split.index(item) == 3:novoContato.telefone = novoItemcontatos.append(novoContato)

Page 140: Python BGE

Python

Uma porção de coisas novas para nós:

a função 'open' retorna um arquivo. Quando executamos uma operação de iteração sobre ele, o que é retornado são suas linhas no formato de lista. A função 'split' separa uma string em pedaços. Esses pedaços são configurados de acordo com outra string, no caso do exemplo, "cortamos" a string nos símbolos de fechamento de chaves. Assim temos uma lista de strings sem esse caractere.

Page 141: Python BGE

Python

A função 'replace' substitui pedaços de string por outros, no exemplo, substituímos as partes que não queríamos (como "[codigo") por um caractere vazio (''), o que remove da string o que não nos serve. A função 'index' retorna o índice de um elemento dentro de uma lista (vetor). Sabendo que o índice do código é 1, do nome é 2 e do telefone é 3, pudemos ver se o item atual era um desses e definir o valor à variável correspondente.A função 'append' adiciona um elemento ao final de uma lista, como você deve se lembrar

Page 142: Python BGE

Python

Com isso, já podemos executar o programa e selecionar a opção para visualizar os contatos. Eles devem aparecer perfeitamente na tela.

Entretanto, ainda é necessário gravar os contatos no arquivo antes de fechar o programa. Para isso, adicione o seguinte ao fim do código todo:

arquivo = open(CAMINHOARQUIVO, 'w')for contato in contatos:linha = '[codigo]' + contato.codigo + '[nome]' + contato.nome + '[telefone]' + contato.telefone + '\n'arquivo.write(linha)

Page 143: Python BGE

Python

Aqui simplesmente abrimos o arquivo no modo de escrita ('w'), o que significa que todo o seu conteúdo será apagado quando ele for aberto. Como já havíamos carregado os dados antes, isso não nos preocupa e é até melhor para evitar duplicidade.

Depois, para cara contato da nossa lista, criamos uma string dentro do nosso padrão (com o '\n' no final) e a gravamos no arquivo.

Como você pode notar, dá um certo trabalho gravar dados em arquivos e essa é uma prática que eu não recomendo (a menos que seja necessário). É muito mais simples e seguro usar um banco de dados para isso.

Page 144: Python BGE

Python

Não é tão difícil programar em Python. É necessário apenas algum tempo conhecendo a sintaxe da linguagem e algum conhecimento em Inglês ajuda nessa tarefa.

A parte mais difícil do processo todo é aprender a abstrair os objetos do mundo real e executar processos através de Lógica de Programação com eles.

Portanto, caso não tenha entendido bem alguma coisa, releia quantas vezes forem necessárias até conseguir.

Existe muito mais sobre Python a se falar, mas para o nosso curso, isso deve ser o suficiente.

Page 145: Python BGE

Banco de dados

Armazenar dados em arquivos não é uma tarefa das mais fáceis e confiáveis, pois somos nós que temos que implementar toda a lógica dessa idéia.

Usar um banco de dados é a melhor alternativa para se armazenar dados, seja de um programa, jogo, ou o que for.

Page 146: Python BGE

Banco de dados

Você se lembra como se parece uma planilha eletrônica (Excel, Calc, etc)? Temos uma tabela com linhas e colunas, certo?

Geralmente, na primeira linha colocamos o nome dos campos, e nas linhas seguintes os dados. Logo, cada coluna representa uma informação diferente, a primeira linha representa a descrição dessa informação e as linhas seguintes representam os dados.

Um banco de dados funciona de forma parecida, exceto que ele nos dá ferramentas para controlar melhor e mais facilmente nossos dados.

Page 147: Python BGE

Banco de dados

Nossa primeira ferramenta de aprendizado será o Base do BrOffice. Recomendo que baixe-o: http://www.broffice.org

Você também pode usar o Microsoft Access se quiser, mas as instruções deste curso serão direcionadas ao Base.

Uma vez instalado, abra-o e vamos começar!

Page 148: Python BGE

Banco de dados

Ao abrir o Base, um assistente será mostrado. Nele, escolha "Criar novo banco de dados" e clique em "Próximo".

Page 149: Python BGE

Banco de dados

Na tela seguinte, marque "Sim, registre o banco de dados para mim" e "Abrir o banco de dados para "Edição". Clique em "Concluir" e salve-o em algum lugar.

Page 150: Python BGE

Banco de dados

A seguir, no menu de tarefas, clique em "Criar tabela no editor".

Page 151: Python BGE

Banco de dados

Crie os campos como mostrado abaixo:

Nada muito complicado, temos um campo (coluna) para o código (tipo numérico), um para o nome (tipo texto) e um para o telefone (tipo texto). Colocamos também uma descrição para cada um.

Page 152: Python BGE

Banco de dados

Clique com o botão direito do mouse sobre o pequeno quadrado antes do campo "codigo" (onde está a seta verde na imagem) e marque "Chave primária":

Uma chave primária é o que identifica um registro (linha) numa tabela. Em resumo, ele é o código daquele registro. Uma chave primária é única, ou seja, não podem haver dois registros com a mesma chave (código).

Page 153: Python BGE

Banco de dados

Clique no botão "Salvar" e salve a tabela com o nome "Contato":

Em seguida, feche o editor de tabelas.

Page 154: Python BGE

Banco de dados

No menu de tabelas, clique duas vezes na tabela "Contato" para abrir o editor de dados:

No editor de dados, crie alguns registros dando um código único a cada um, salve e feche o editor de registros:

Page 155: Python BGE

Banco de dados

Vamos parar para analisar a teoria por trás do que fizemos (ou melhor, o Base fez para nós).

Como já foi dito, uma tabela funciona de forma parecida com uma planilha (Excel, Calc), sendo que em cada coluna é colocado um campo diferente (nome, telefone,...) e em cada linha é colocado um registro diferente.

Cada registro é identificado pela chave primária, que é uma espécie de código. A chave primária deve ser única para cada registro na tabela. Caso você tente inserir um registro com uma chave primária que já existe receberá um erro.

Page 156: Python BGE

Banco de dados

A forma como se define uma tabela não difere muito da forma como se define uma classe em algoritmos, sendo que cada atributo (campo) deve ter um nome e um tipo de dados.

Ao inserir um novo registro numa tabela, uma nova linha é criada e ela se parece cada vez mais com uma planilha eletrônica.

O Base nos dá ferramentas simples para criar tabelas e inserir registros dentro delas, mas por trás dos panos, o que ele faz mesmo é executar comandos SQL.

Page 157: Python BGE

Banco de dados

SQL (Structed Query Language) é a linguagem que os bancos de dados entendem e com ela é possível criar tabelas, inserir registros, consultar registros, remover tabelas e registros, etc.

Para começar, vamos aprender o comando SQL para consultar registros dentro de uma tabela. Ele é composto por três partes:

O que deve ser selecionadoDe onde deve ser selecionadoComo deve ser selecionado

Page 158: Python BGE

Banco de dados

Portanto, se quisermos selecionar todos registros da tabela Contato, faríamos assim:

SELECT *FROM Contato

Aqui selecionamos ('SELECT') todos os campos ('*') da tabela Contato ('FROM Contato'). Como você já sabe, a consulta é dividida em três partes, mas a última (como deve ser selecionado) não é obrigatória.

Page 159: Python BGE

Banco de dados

Vá até o Base e clique no botão "Consultas", depois em "Criar consulta no editor de SQL":

Na nova tela que se abre, coloque o comando do slide anterior e tecle F5 para executá-lo.

Page 160: Python BGE

Banco de dados

Como resultado temos todos os registros da tabela Contato:

Page 161: Python BGE

Banco de dados

Vamos ser um pouco mais específicos agora e selecionar apenas o registro com código 2:

SELECT *FROM ContatoWHERE codigo = 2

O comando WHERE (onde) é a terceira parte da consulta, ou seja, como deve ser consultado. Em outras palavras, o WHERE é a condição.

Page 162: Python BGE

Banco de dados

E aí está o resultado da nossa consulta mostrando apenas o registro com código igual a 2:

Page 163: Python BGE

Banco de dados

Também é possível filtar os valores por faixas, como no exemplo:

Aqui filtramos o resultado para mostrar apenas os que tem o código igual a um dos elementos dentro ('IN') da lista.

Page 164: Python BGE

Banco de dados

Também é possível filtrar textos:

Aqui filtramos a consulta para mostrar apenas os registros que tem o campo nome com valor exatamente igual a 'Fulano de Tal'.

Page 165: Python BGE

Banco de dados

Se quiséssemos saber os nomes que terminam com 'de Tal', faríamos assim:

SELECT *FROM ContatoWHERE nome LIKE '%de Tal'

O comando LIKE (parecido, próximo) nos permite filtrar textos de forma a termos mais controle sobre o que será mostrado.

O símbolo '%' quer dizer que não importa o que venha antes de 'de Tal'. Contanto que o registro termine assim, ele deve ser mostrado.

Page 166: Python BGE

Banco de dados

O '%' é um caractere coringa na filtragem de strings pelo comando LIKE. Além dele, também pode ser usado o '_'. Vejamos a diferença entre eles:

%: qualquer seqüencia de caracteres antes ou depois dele deve ser ignorada, por exemplo: '% de Tal' irá ignorar o que estiver antes, enquanto que 'Fulano%' irá ignorar o que estiver depois._: parecido com o %, exceto que ele ignora apenas um caractere. Por exemplo: '_anderlei' nos resultaria tanto 'Wanderlei' quando 'Vanderlei'.

Page 167: Python BGE

Banco de dados

Também é possível colocar mais de uma condição:

SELECT *FROM ContatoWHERE nome LIKE '%de Tal'AND telefone LIKE '(42)%'

Aqui queremos todos os registros que tem nomes terminando com 'de Tal' e telefones começando com '(42)'.

Page 168: Python BGE

Banco de dados

Também é possível selecionar apenas alguns campos:

SELECT codigo, telefoneFROM Contato

Nesse caso, o campo 'nome' não seria mostrado.

Page 169: Python BGE

Banco de dados

Para tornar as coisas mais interessantes, vamos criar a tabela "Endereco" e preenchê-la com alguns dados:

Page 170: Python BGE

Banco de dados

E se quiséssemos que nossos contatos da tabela Contato tivessem um endereço?

Para isso, precisamos editar a tabela Contato e criar um campo lá. Para isso, clique em Tabelas, depois clique com o botão direito sobre a tabela Contato e clique em "Editar". Uma vez aberta, crie o campo 'codEndereco' com o mesmo tipo usado no campo 'codigo' da tabela "Endereco".

Page 171: Python BGE

Banco de dados

Salve e feche a tabela e vá no menu Ferramentas - Relações. Na janela que se abre, adicione as duas tabelas, depois feche a janela "Adicionar tabelas".

Page 172: Python BGE

Banco de dados

A seguir, na tabela Contato, clique sobre o campo 'codEndereco' e arraste-o em cima do campo 'codigo' da tabela Endereco:

O relacionamento será criado:

Page 173: Python BGE

Banco de dados

Salve e feche a janela. Agora vamos entender o que é um relacionamento.

Não precisamos colocar todas as informações em uma só tabela. Isso desorganizaria tudo e deixaria o banco de dados difícil de lidar.

Ao invés disso, podemos separar as informações em tabelas diferentes e criar relacionamento entre elas.

Page 174: Python BGE

Banco de dados

Um relacionamento é basicamente uma ligação entre uma tabela e outra. Para criar um relacionamento, é necessário um campo na tabela referenciadora do mesmo tipo de dados da chave primária da tabela referenciada.

Entretando, isso não é o suficiente, é necessário especificar o relacionamento. No idioma de bancos de dados, um relacionamento é uma chave estrangeira, ou seja, um campo que contém o valor da chave primária de outra tabela.

Page 175: Python BGE

Banco de dados

Os tipos de relacionamento são:

1-1: diz ao banco de dados que cada registro na tabela A deve corresponder a apenas um registro na tabela B, por exemplo: uma pessoa só pode ter um CPF.1-n: cada registro na tabela A pode corresponder a vários registros na tabela B, por exemplo: uma pessoa pode ter vários endereços.n-n: vários registros na tabela A podem corresponder a vários registros na tabela B, por exemplo: várias pessoas podem comprar em várias lojas diferentes.

Page 176: Python BGE

Banco de dados

Uma relação N-N deve ser convertida em uma nova tabela, caso contrário a organização dos dados ficaria muito confusa.

Usando o mesmo exemplo das pessoas que comprar em várias lojas, deveríamos criar uma tabela do tipo "Pessoa_Loja" para nos dizer qual pessoa corresponde a qual loja e vice-versa.

A tabela Pessoa teria uma relação 1-N com essa tabela, assim como essa nova tabela teria uma relação N-1 com a tabela Loja.

Page 177: Python BGE

Banco de dados

Continuando, vamos usar o editor de dados para dar um endereço aos nossos contatos:

Note que se você tentar informar um código de endereço que não exista, receberá um erro.

Page 178: Python BGE

Banco de dados

Agora, como podemos selecionar os dados do endereço junto com os dados do contato?

SELECT *FROM Contato cINNER JOIN Endereco e ON e.codigo = c.codEndereco

Aqui demos um apelido ('c') à tabela Contato e a unimos ('INNER JOIN') com a tabela Endereco. Para realizar uma união é necessária uma condição ('ON').

No exemplo, a união é feita quando o código do endereço é igual ao valor do campo 'codEndereco' da tabela Contato.

Page 179: Python BGE

Banco de dados

Assim, temos como resultado:

Page 180: Python BGE

Banco de dados

Novamente, podemos escolher os campos que queremos mostrar:

Page 181: Python BGE

Banco de dados

Também podemos continuar filtrando normalmente:

Page 182: Python BGE

Banco de dados

Para inserir um registro dentro de uma tabela o comando é o seguinte:

INSERT INTO Contato (codigo, nome, telefone)VALUES (4, 'Aparecido de Jesus', '(53) 3433-334')

Esse comando não é compatível com o Base, embora seja SQL padrão.

O comando INSERT tem como parâmetro o nome da tabela e quais campos serão preenchidos. O comando VALUES recebe os valores que serão inseridos. A ordem dos valores (VALUES) será a mesma informada no INSERT.

Page 183: Python BGE

Banco de dados

Para alterar um registro:

UPDATE ContatoSET telefone = '(33) 3333-3333'WHERE codigo = 1

O comando de alteração (UPDATE) precisa de novos valores (SET) e uma condição (WHERE). Caso seja necessário alterar mais de um valor, basta separar com vírgula.

UPDATE ContatoSET telefone = '(33) 3333-3333',nome = 'Não sou mais Fulano de Tal'WHERE codigo = 1

Page 184: Python BGE

Banco de dados

Para remover um registro:

DELETE FROM ContatoWHERE codigo = 3

Esse comando não precisa de muita explicação. Ele irá apagar (DELETE) da tabela especificada os valores que corresponderem à condição (WHERE).

Page 185: Python BGE

Banco de dados

Eu devo confessar que o Base não é um dos melhores sistemas de bancos de dados que existe.

Para cada necessidade existe um sistema diferente, por exemplo: o Oracle e o SQL Server são excelentes para trabalhar com grandes quantias de dados e de requisições, enquanto que o Firebird é ótimo para aplicações pequenas.

O Base nos foi muito útil até agora, mas apenas como ferramenta de aprendizado. Chegou a hora de partir para algo novo e mais completo.

Page 186: Python BGE

Banco de dados

Em primeiro lugar, quero que baixe e instale o SQLite Administrator: http://sqliteadmin.orbmu2k.de/

Ele é uma ferramenta gráfica para o sistema SQLite, que é um banco de dados leve e indicado para aplicações pequenas.

A parte boa do SQLite é que não é necessário um servidor para que ele seja acessado, como geralmente acontece com os sistemas de bancos de dados mais robustos.

Como um jogo (exceto se for um MMO) não precisa de um banco de dados muito poderoso, o SQLite nos cai como uma luva.

Page 187: Python BGE

Banco de dados

Vamos recriar o banco de dados original que desenvolvemos para a nossa Agenda. No SQLite Administrator, clique no botão "Criar Banco de Dados" e salve-o na mesma pasta do arquivo "agenda.py"

Page 188: Python BGE

Banco de dados

Agora vamos criar a tabela Contato. Para isso, clique com o botão direito sobre "Tabelas" e depois em "Criar tabela".

Page 189: Python BGE

Banco de dados

Dê um nome à tabela e adicione o campo 'CODIGO', configurado como sendo do tipo numérico, como chave primária e como autoincremento.

Page 190: Python BGE

Banco de dados

Autoincremento quer dizer que o campo terá seu valor preenchido automaticamente. Sempre com um valor maior que o último. Agora crie os demais campos:

Page 191: Python BGE

Banco de dados

Quando terminar, clique em "Criar". Feito isso, selecione a tabela "Contato" e vá até o editor de dados para adicionar alguns registros:

Page 192: Python BGE

Banco de dados

Quando terminar, clique no botão "Post" para que os dados seja, de fato, gravados. Depois disso você pode fechar o SQLite Administrator.

Page 193: Python BGE

Banco de dados

Abra o arquivo "agenda.py" e remova o seguinte trecho:

for linha in open (CAMINHOARQUIVO):split = linha.split(']')novoContato = Contato(None, None, None)

for item in split:novoItem = item.replace('[codigo', '').replace('[nome', '')novoItem = novoItem.replace('[telefone', '').replace('\n', '')novoItem = novoItem.replace('\xef\xbb\xbf', '')if split.index(item) == 1:novoContato.codigo = novoItemelif split.index(item) == 2:novoContato.nome = novoItemelif split.index(item) == 3:novoContato.telefone = novoItemcontatos.append(novoContato)

Page 194: Python BGE

Banco de dados

Remova também este trecho:

arquivo = open(CAMINHOARQUIVO, 'w')for contato in contatos:linha = '[codigo]' + contato.codigo + '[nome]' + contato.nome + '[telefone]' + contato.telefone + '\n'arquivo.write(linha)

Page 195: Python BGE

Banco de dados

Altere o seguinte trecho:

#-*- coding: utf-8 -*-import osCAMINHOARQUIVO = os.path.dirname(os.path.abspath(__file__)) + '\\agenda.txt'

Para isto:

#-*- coding: utf-8 -*-import sqlite3import os

conexao = sqlite3.connect(os.path.dirname(os.path.abspath(__file__)) + '\\banco.s3db')cursor = conexao.cursor()

Page 196: Python BGE

Banco de dados

NO trecho que adicionamos, importamos o módulo 'sqlite3', criamos a conexão com nosso novo banco de dados e criamos um cursor que atua sobre a conexão.

Um cursor é um objeto que é capaz de interagir com o banco de dados nos permitindo executar comandos SQL e trabalhar com os dados retornados por eles.

Page 197: Python BGE

Banco de dados

Altere a classe contato para que fique assim:

class Contato:codigo = Nonenome = Nonetelefone = None

def __init__ (self, novoNome, novoTelefone):self.nome = novoNomeself.telefone = novoTelefone

Aqui removemos o parâmetro 'codigo' do construtor. Fizemos isso, pois o banco de dados irá se encarregar de gerar um código para nós (autoincremento).

Page 198: Python BGE

Banco de dados

Abaixo do trecho:

contatos = []op = 0

Adicione:

cursor.execute('SELECT * FROM CONTATO')

for linha in cursor:novoContato = Contato(linha[1], linha[2])novoContato.codigo = linha[0]contatos.append(novoContato)

Page 199: Python BGE

Banco de dados

O que fizemos foi executar uma SQL para selecionar todos os contatos do banco de dados. Isso retorna ao cursor uma lista de dados.

Para cada registro retornado, criamos um novo objeto Contato e o adicionamos à lista de contatos do nosso programa.

Cada registro é retornado na forma de lista, portanto precisamos do índice de cada campo para saber seu valor.

Page 200: Python BGE

Banco de dados

Altere o trecho que trata a opção número 2 para que fique assim:

elif op == 2:print 'Nome: 'nome = raw_input()print 'Telefone: 'telefone = raw_input()novoContato = Contato (nome, telefone)cursor.execute("INSERT INTO CONTATO(nome, telefone) VALUES('" + nome + "','" + telefone + "')")conexao.commit()cursor.execute('select * from contato where codigo = (select max(codigo) from contato)')for linha in cursor:novoContato.codigo = linha[0]contatos.append(novoContato)

Page 201: Python BGE

Banco de dados

O que fizemos foi executar uma SQL de inserção (INSERT) contendo os dados do novo registro criado pelo usuário.

Note que quando o valor de um campo é string, ele deve estar entre aspas simples ('') na SQL. Por isso usamos os dois tipos de aspas aqui.

Depois, chamamos o comando 'commit' do objeto de conexão, o que vai efetuar, de fato, a gravação dos dados. Finalmente executamos uma SQL que seleciona o ultimo registro adicionado e coloca o valor do campo código no novo registro e o adiciona à lista.

Page 202: Python BGE

Banco de dados

Altere a opção número 3 para ficar assim:

elif op == 3:print u'Código: 'codigo = int(raw_input())for contato in contatos:if contato.codigo == codigo:print 'Novo nome: 'contato.nome = raw_input()print 'Novo telefone: 'contato.telefone = raw_input()cursor.execute("UPDATE CONTATO SET nome = '" + contato.nome + "', telefone = '" + contato.telefone +"' WHERE codigo = " + str(codigo))conexao.commit() break

Page 203: Python BGE

Banco de dados

Aqui não mudou muito, simplesmente no fim do código colocamos uma SQL que atualiza (UPDATE) o registro com o código especificado.

Como no banco de dados o campo 'codigo' é do tipo numérico, foi necessário fazer o casting da entrada de dados do usuário ('int(raw_inuput())').

Page 204: Python BGE

Banco de dados

Altere a opção 4 para ficar assim:

elif op == 4:print u'Código: 'codigo = int(raw_input())for contato in contatos:if contato.codigo == codigo:cursor.execute('DELETE FROM CONTATO WHERE codigo = ' + str(codigo))contatos.remove(contato)print 'Contato removido!'break

Novamente, não houve uma grande mudança, apenas a colocação da SQL que remove (DELETE) o registro do banco de dados.

Page 205: Python BGE

Banco de dados

Com isso, nosso programa da agenda já deve funcionar perfeitamente com o banco de dados.

Note que a implementação da idéia tornou-se mais fácil com o uso do banco de dados do que foi quando usamos arquivos.

Basta ter uma conexão, um cursor, alguns comandos SQL para cada finalidade e pronto!

Page 206: Python BGE

Banco de dados

Isso é tudo que você precisa saber por enquanto sobre banco de dados. Recomendo que reveja as partes que não entendeu antes de prosseguir.

Como sempre, ainda existe muito a se falar sobre banco de dados. O que aprendemos aqui foi o básico da DML (Data Manipulation Language), que serve para trabalhar especificamente com os dados e não com a estrutura do banco de dados em si.

Page 207: Python BGE

BGEEscrever programas para console não é lá muito empolgante, não é?

É agora que as coisas começam a ficar mais interessantes - e mais ilustradas, prometo!

Para essa parte do curso, o requerimento é algum conhecimento básico do Blender.

Page 208: Python BGE

BGE

Se você não for necessariamente um expert em modelagem, texturização, animação, etc... o melhor a se fazer é utilizar modelos prontos que podem ser baixados nos repositórios que já indiquei anteriormente.

Deste ponto em diante, vou realmente precisar que você conheça pelo menos o básico do Blender. Caso não conheça, então recomendo que procure alguns tutoriais básicos sobre a interface do programa, modelagem, animação, texturização, etc.

Pronto para começar?

Page 209: Python BGE

BGEPor enquanto, nossos objetos de aprendizado serão os que já são criados na cena padrão do Blender (cubo, lamp e camera).

Antes da diversão realmente começar, devemos conhecer o fabuloso mundo dos Logic Bricks.

Para isso, selecione o cubo como na imagem e tecle F4 para ir ao Painel de Lógica.

Page 210: Python BGE

BGE

Esse painel é dividido em duas partes: a configuração do ator (actor) e as configurações dos blocos de lógica (logic bricks):

Note que as configurações dos blocos de lógica são dividos em três: sensores (sensors), controladores (controllers) e atuadores (actuators).

Page 211: Python BGE

BGE

O ator é o próprio objeto (no caso, o cubo) como uma entidade dentro da BGE, ou seja, dentro do jogo ele não é mais um objeto do Blender, mas sim da BGE.

A primeira configuração que devemos observar é o tipo de objeto (Object type).

Note que, por padrão, o tipo de objeto é definido como static (estático).

Page 212: Python BGE

BGE

O primeiro tipo é o soft body. Esse tipo de objeto deforma com colisões físicas. Suas propriedades são:

Actor: diz à BGE para calcular a Física do objetoGhost: faz com que o objeto possa atravessar outros objetosInvisible: o objeto não aparecerá no jogoAdvanced: configurações avançadas de colisãoMass: quantidade de força necessária para mover o objetoShape Match: habilita a deformação conforme a formaBending const: habilita restrições de deformaçãoLinStiff: rigidez linear das juntas do softbodyFriction: fricção físicaKMT: início da deformação conforme a forma

Page 213: Python BGE

BGE

O segundo tipo é o rigid body. Esse tipo de objeto é duro, ao contrário do soft body e tende a rolar. Suas propriedades são:

Actor: diz à BGE para calcular a Física do objetoGhost: faz com que o objeto possa atravessar outros objetosInvisible: o objeto não aparecerá no jogoAdvanced: configurações avançadas de colisãoMass: quantidade de força necessária para mover o objetoRadius: tamanho da área de cálculo da Física do objetoNo sleeping: calcula a Física no objeto, mesmo em repousoDamp: resistência ao movimento do objetoRotDamp: resistência à rotação do objetoDoFh: habilita o suporte às propriedades físicas de material

Page 214: Python BGE

BGE

RotFh: usa as normais das faces para o calculo do DoFhForm: fator de inércia na Física do objetoAnistropic: quantidade de fricção nos eixos X, Y e Z

O tipo de objeto dynamic é praticamente idêntico ao rigid body e a diferença é que o rigid body é específico para objetos que tendem a rolar, enquanto que o dynamic não é.

Page 215: Python BGE

BGE

O quarto tipo é o static. Esse tipo de objeto é duro, mas não é afetado pela gravidade. Suas propriedades são:

Actor: diz à BGE para calcular a Física do objetoGhost: faz com que o objeto possa atravessar outros objetosInvisible: o objeto não aparecerá no jogoAdvanced: configurações avançadas de colisãoAnistropic: quantidade de fricção nos eixos X, Y e Z

Page 216: Python BGE

BGE

O quinto tipo é o sensor. Esse tipo de objeto não colide com outros, ou seja, eles o atravessam. Ele detecta objetos rigid body e dynamic, mas não detecta outros objetos do tipo sensor. Suas propriedades são:

Detect Actor: detecta apenas objetos com a propriedade Actor ativadaInvisible: o objeto não aparecerá no jogo Advanced: configurações avançadas de colisão

Page 217: Python BGE

BGE

O sexto tipo é o no collision. Esse tipo de objeto, assim como o sensor, não é afetado pela física e deve ser usado quando nenhum objeto pode colidir com ele, pois os objetos o atravessarão.

Ele possui apenas a propriedade Invisible que faz com que o objeto não apareça no jogo.

Page 218: Python BGE

BGE

O sexto tipo é o occluder. Esse tipo de objeto não colide com outros, ou seja, eles o atravessam. Ele tem a função de impedir que objetos que estejam atrás dele sejam mandados para a placa de vídeo. Isso é feito para economizar processamento em alguns casos.

Ele possui apenas a propriedade Invisible que faz com que o objeto não apareça no jogo.

Page 219: Python BGE

BGE

Para os tipos de objetos que colidem, existe a configuração dos bounds, ou seja, dos tipos de áreas de cálculo da Física para um objeto.

Como calcular a Física para cada face de um objeto com muitos vértices usaria muito processamento, a BGE trata o objeto como uma forma mais simples, como um cubo ou uma esfera para economizar processamento. É exatamente isso que os bounds fazem.

Os tipos triangle mesh e convex hull devem ser usados para cálculos mais precisos, como a colisão de um soft body numa árvore, por exemplo.

Page 220: Python BGE

BGE

Um objeto da BGE também pode possuir algumas propriedades (properties), que nada mais são do que variáveis. Elas podem ser do tipo timer (cronômetro), String (caracteres), float (número decimal), int (número inteiro) e bool (lógico).

Para as propriedades temos:

Del: remove a variávelType: tipo de dadoName: nome da variávelValue: valor da variávelD: mostra o valor da variável no modo de depuração (debug)

Page 221: Python BGE

BGE

Sensores são entidades que capturam sinais, ou seja, eventos específicos que acontecem no jogo. Como vários sinais diferentes são enviados em um jogo, a BGE nos oferece vários tipos de sensores.

O primeiro deles, o Always, retorna um sinal Verdadeiro o tempo todo, ou seja, ele não é bem um sensor, mas uma ferramenta para coisas dentro do jogo que precisar executar sem parar, como tocar músicas de fundo, por exemplo.

Page 222: Python BGE

BGE

Assim como todos os sensores, o Always tem os seguintes parâmetros:

True level triggering: faz com que o retorno seja VerdadeiroFalse level triggering: faz com que o retorno seja Falsof: intervalo (em momentos) entre um retorno e outroLevel: faz o sensor detectar statesTap: o sensor retornará apenas uma vez, mesmo que seja do tipo Always. Bom para fazer inicializações.Inv: inverte o retorno do sensor (de Verdadeiro para Falso e vice versa)

Page 223: Python BGE

BGEO parâmetro 'f' é calculado da seguinte forma:

Na BGE, 60 pulsos são 1 segundof=1: o sensor retorna uma vez a cada pulso, ou seja, 60 retornos por segundof=30: retorna uma vez a cada 30 pulsos, ou seja, 2 retornos por segundof=60: retorna uma vez a cada 60 pulsos, ou seja, 1 vez por segundo

Page 224: Python BGE

BGE

O tipo de sensor Delay nos oferece um maior controle sobre os intervalos entre um retorno e outro. Seus parâmetros são:

Delay: intervalo (em momentos) entre um retorno e outroDur: duração do retorno (em momentos)REP: reinicia o sensor depois que o retorno é enviado

Page 225: Python BGE

BGE

O tipo Keyboard nos permite capturar teclas pressionadas pelo jogador enquanto o jogo estiver sendo executado. Seus parâmetros são:

Key: define uma tecla a ser capturada pelo sensorAll keys: captura qualquer tecla pressionadaHold: teclas a serem seguradas enquanto se tecla a primeira. Se key for 'W' e não houver Hold, o personagem anda. Se key for 'W' e houver hold em 'Shift', o personagem corre.Log Toggle: variável Bool, que determina se haverá ou não log de teclas.Target: variável String onde o log será armazenado.

Page 226: Python BGE

BGE

O Sensor do tipo Mouse, nos permite caputar eventos realizados com o mouse. Suas opções são:

Left button: clique com o botão esquerdoRight button: clique com o botão direitoMiddle button: clique com o botão do meioWheel up: scroll para cimaWheel down: scroll para baixoMovement: movimento do ponteiroMouse over: ponteiro está sobre o objeto em que está definido este sensor.Mouse over any: ponteiro está sobre qualquer objeto.

Page 227: Python BGE

BGE

O sensor do tipo Touch nos permite saber quando nosso objeto está em contato (encosta) com outro. Quando o valor de "MA" não está preenchido, retorna Verdadeiro sempre que nosso objeto entra em contato com qualquer objeto na cena.

Se o valor de "MA" for preenchido com o nome de um material, o sensor só irá retornar Verdadeiro quando nosso objeto entrar em contato com objetos que estejam configurados com o material em questão.

Page 228: Python BGE

BGE

O sensor do tipo Collision é parecido com o Touch, a diferença é que o Collision filtra os objetos por propriedade. Os parâmetros são:

Pulse: permite ao sensor detectar mais de uma colisão ao mesmo tempoM/P: alterna entre o filtro por material e por propriedadeProperty: define a propriedade (variável) a ser filtrada. Somente objetos que possuam essa propriedade serão detectados.

Page 229: Python BGE

BGE

O sensor do tipo Near detecta se o objeto está a uma determinada distância de outros objetos. Seus parâmetros são:

Property: filtra apenas objetos com uma determinada propriedade.Dist: distância (em unidades) dos objetos detectados para retornar VerdadeiroReset: distância (em unidades) dos objetos detectados para retornar Falso

Page 230: Python BGE

BGE

Uma unidade da BGE é igual a uma unidade do Blender. Um modo fácil de medir é observar o número de "quadrados" na grid da 3D View.

O cubo padrão (imagem) tem duas unidades de largura, duas de altura e duas de comprimento.

Isso pode ser provado colocando o cubo em modo de edição (TAB) indo até o painel de edição (F9) e habilitando-se a opção Edge Length (largura de arestas).

Page 231: Python BGE

BGE

Page 232: Python BGE

BGE

O sensor do tipo Radar funciona de forma parecida com o Near, exceto que o Radar funciona apenas para um eixo. Seus parâmetros são:

Prop: filtro de objetos por propriedadeType: eixo e direção a serem utilizadosAng: ângulo de abertura do sensorDist: distância de alcance do sensor

Page 233: Python BGE

BGE

Vamos comparar um sensor Near e um sensor Radar:

Near: cria um raio de 360º e tamanho determinado em volta de si.

Radar: cria um raio de ângulo e tamanho determinados em volta de si. O "cone" de detecção irá atuar em somente um eixo.

Page 234: Python BGE

BGE

O sensor do tipo Property nos permite avaliar o valor de uma determinada propriedade. Seus parâmetros são:

Type: tipo de verificação. Pode ser equal (igual a), not equal (diferente de), interval (está entre) e changed (mudou)O parâmetro que aparece abaixo disso depende do tipo de verificação escolhido. Value é um valor determinado, min e max definem a faixa de comparação para o tipo interval.

Page 235: Python BGE

BGE

O sensor do tipo Random retorna pulsos de forma aleatória, ou seja, não há como se saber se o retorno vai ser Verdadeiro ou Falso, pois ele retorna hora um, hora outro.

O parâmetro Seed refere-se a um valor inicial para a geração dos sinais aleatórios. Se for igual a zero, o retorno não será aleatório.

Page 236: Python BGE

BGE

O sensor do tipo Ray funciona de forma parecida com o Radar, exceto pelo fato de que ele "dispara" um raio na direção de um determinado eixo . O raio segue pelo eixo até colidir com um objeto qualquer ou que possua uma determinada propriedade. Assim que isso acontece, o sensor retorna verdadeiro.

O botão X diz ao raio para atravessar objetos que não possuam a propriedade especificada e continuar procurando.

O parâmetro Range, determina a distância máxima de alcance do raio.

O parâmetro Type especifica o eixo e a direção do "disparo".

Page 237: Python BGE

BGE

O sensor do tipo Message detecta quando uma mensagem é enviada pelo jogo. Falaremos sobre mensagens mais adiante.

O sensor também permite filtrar as mensagens por um assunto (Suject) específico.

Page 238: Python BGE

BGE

O sensor do tipo Joystick trata eventos de um gamepad. Seus parâmetros são:

Index: qual joystick usar (caso haja mais de um). O valor 0 indica o primeiro joystickType: tipo do evento a ser detectado no joystickO parâmetro de baixo muda conforme o tipo de evento escolhido. Em suma, o tipo hat trata dos comandos direcionais digitais, axis trata dos comandos direcionais analógicos, single axis trata de um eixo em particular nos analógicos e button trata os botões de comando.

Page 239: Python BGE

BGE

Page 240: Python BGE

BGE

O sensor do tipo Actuator detecta quando um atuador (mais tarde falaremos deles) é ativado.

Para que funcione, é necessário especificar um atuador no parâmetro Act.

Page 241: Python BGE

BGE

Controladores são entidades que avaliam o retorno dos sensores, realizam validações neles e retornam um pulso aos atuadores.

Somente dois deles precisam de parâmetros exatos: Python e Expression. Todos os demais utilizam apenas os sensores conectados a eles para fazer a validação.

Page 242: Python BGE

BGE

Em resumo os tipos de controladores são:

AND: todos os sensores conectados devem retornar Verdadeiro para que o controlador retorne VerdadeiroOR: um ou mais sensores devem retornar VerdadeiroXOR: apenas um sensor deve retornar VerdadeiroNOR: nenhum sensor deve retornar VerdadeiroXNOR: todos os sensores devem retornar o mesmo valor (Verdadeiro ou Falso)Expression: permite avaliar através de uma expressãoPython: permite avaliar através de um script em Pyhton (falaremos disso mais tarde)

Page 243: Python BGE

BGE

Um exemplo de expressão seria:

Nesse caso, o sensor Always retorna sempre Verdadeiro, mas a condição definida na expressão diz que além disso, é preciso que "propriedade" seja igual a um, logo esse controlador não irá retornar Verdadeiro.

Page 244: Python BGE

BGE

Atuadores são entidades que afetam o jogo ou os objetos dele de alguma forma. Em resumo: eles executam uma ação.

O primeiro deles, o Motion move o objeto no qual está configurado (ator). Há dois tipos de movimento: simple e servo.

Page 245: Python BGE

BGE

O Simple motion aplica movimento e rotação a um objeto em eixos determinados. O parâmetro Loc refere-se à quantia de movimento nos eixos X, Y e Z, enquanto que o parâmetro Rot refere-se à quantia de rotação nesses eixos.

O Servo motion aplica força (torque) a um objeto de forma a tornar sua movimentação mais natural, uma vez que no mundo real a velocidade de um corpo é resultado da força que ele usou para conseguí-la.

Logo, o Servo só funciona para objetos do tipo que recebem cálculos de Física.

Page 246: Python BGE

BGE

Os parâmetros do Servo motion são:

Ref: objeto de referência para o cálculo (uma plataforma móvel, por exemplo)LinV: velocidade linear de referência. O atuador tenta se manter na velocidades especificadas aquiLimit: limita a velocidade nos eixos. Pode-se especificar velocidades mínimas e máximas para cada eixoP: coeficiente proporcional de erroI: coeficiente integral de erroD: coeficiente derivado de erro

Page 247: Python BGE

BGE

O coeficiente de erro do Servo é a diferença entre a força atual e a força especificada no parâmetro LinV.

Quando a força está diferente, o Servo aplica uma nova força ao objeto. Essa força é proporcional ao erro atual (P) e também à sua integral (I), que a soma dos erros mais recentes.

O coeficiente derivado é baseado na freqüência com que o erro se altera.

Page 248: Python BGE

BGE

O atuador do tipo Shape Action trabalha com as shapekeys que um objeto possui. Os tipos são:

Play: executa a animação inteira uma vez (Play)Flipper: executa para frente (frames 1, 2, 3) quando for verdadeiro e para trás (frames 3, 2, 1) quando for falsoLoop Stop: repete a animação inteira enquanto for verdadeiro e a pausa quando for falsoLoop End: repete a animação inteira enquanto for verdadeiro e a reinicia quando for falsoProperty: enquanto for verdadeiro, o frame atual é definido por uma propriedade

Page 249: Python BGE

BGE

O parâmetro AC recebe o nome da action a ser executada. Sta refere-se ao frame inicial da animação, assim como End refere-se ao frame final.

Blendin é ao número de quadros de sobreposição (transição) entre uma animação e outra. Suaviza a troca de animações.

Page 250: Python BGE

BGE

Priority indica a prioridade com que a animação deve ser executada caso várias animações sejam executadas ao mesmo tempo. Quando mais baixo o valor, maior a prioridade.

FrameProp recebe uma variável que irá armazenar o frame atual.

O botão Continue indica que a animação iniciará no frame em que parou da ultima vez que foi executada. Se estiver desligado, a animação irá começar sempre do começo.

Page 251: Python BGE

BGE

O atuador do tipo Action pode ser usado apenas por armatures e funciona de forma semelhante ao Shape Action, exceto pelo fato de que ele é específico para actions de armature.

Os parâmetros são os mesmos do Shape Action, por isso não convém repetir o que já foi explicado.

Page 252: Python BGE

BGE

O atuador do tipo Constraint serve para limitar a movimentação, a rotação e a distância dos objetos. Seus tipos são:

Location: limita a área na qual o objeto pode se moverDistance: limita a distância que um objeto pode ficar de outroOrientation: limita a rotação do objeto em cada eixoForce field: limita a distância e repele o objeto do outro

Page 253: Python BGE

BGE

Para o tipo Location temos:

damp: atraso (em frames) para que a limitação ocorraLimit: eixo e direção da limitaçãoMin: tamanho mínimo da área de limitaçãoMax: tamanho máximo da área de limitação

Page 254: Python BGE

BGE

Para o Distance temos:

damp: atraso (em frames) para que a limitação ocorraDirection: eixo e direção da limitaçãoRange: tamanho da área de cálculoM/P: alterna entre o filtro por material ou propriedadeProperty: somente limita se o objeto contiver a propriedadePER: torna a limitação ativa o tempo todotime: tempo máximo que a limitação fica ativarotDamp: atraso (em frames) para a rotaçãoN: usa as normais do objeto para calcular a limitaçãoDist: distância a ser mantida do objeto

Page 255: Python BGE

BGE

Para o Orientation temos:

damp: atraso (em frames) para que a limitação ocorraDirection: eixo e direção da limitaçãoX: cosseno do ângulo no eixo XY: cosseno do ângulo no eixo YZ: cosseno do ângulo no eixo Ztime: tempo máximo que a limitação fica ativaMin: ângulo mínimo do objetoMax: ângulo máximo do objeto

Page 256: Python BGE

BGE

Para o Force field temos:

damp: atraso (em frames) para que a limitação ocorraDirection: eixo e direção da limitaçãoFh: força de repulsãoM/P: alterna entre o filtro por material ou propriedadeProperty: somente limita se o objeto contiver a propriedadePER: torna a limitação ativa o tempo todotime: tempo máximo que a limitação fica ativarotDamp: atraso (em frames) para a rotaçãoN: usa as normais do objeto para calcular a limitaçãodist: distância a ser mantida do objetoRotFh: deixa o objeto paralelo ao outro

Page 257: Python BGE

BGE

O atuador do tipo Ipo serve para controlar animações com curvas Ipo. Seus tipos e parâmetros são bastante parecidos com os do tipo Action, exceto por:

Tipo Ping Pong: irá alternar entre animação para frente (Sta para End) e para trás (End para Sta) sempre que for verdadeiroChild: aplica o atuador aos objetos que têm parent com o atorForce: converte o Ipo em força (física)Add: soma os valores da Ipo ao atuais do objeto.

Page 258: Python BGE

BGE

O atuador do tipo Camera é feito para seguir outro objeto de maneira suave. Qualquer objeto pode usá-lo. Seus parâmetros são:

OB: nome do objeto a ser seguidoHeight: altura que a câmera deverá tentar manter do centro do objeto seguidoMin: distância mínima que a câmera deverá tentar manter do centro do objeto seguido.Max: distância máxima que a câmera deverá tentar manter do centro do objeto seguido.X e Y: define em qual eixo a câmera será colocada.

Page 259: Python BGE

BGE

O atuador do tipo Sound é usado para reproduzir sons dentro da BGE. Seus tipos são:

Play Stop: toca desde o início e pára quando o som terminar ou o atuador for falso.Play End: toca desde o início, pára quando o som termina e reinicia quando for verdadeiro.Loop Stop: toca e reinicia enquanto for verdadeiro.Loop End: toca sem parar (mesmo que seja falso) e reinicia quando for verdadeiro.Loop Ping Pong Stop: toca e reinicia enquanto for verdadeiro, tocando também de trás para frente.

Page 260: Python BGE

BGE

Loop Ping Pong: toca sem parar e reinicia quando for verdadeiro, além de tocar também de trás para frente.

Os parâmetros são:

Volume: volume do som (de 0 a 1)Pitch: tom/velocidade do som (de -12 a 12)

Page 261: Python BGE

BGE

O atuador do tipo property serve para alterar as propriedades (variáveis) do ator. Seus tipos são:

Add: soma um valor a uma propriedadeAssign: atribui um valor a uma propriedadeCopy: copia o valor de uma propriedade de outro objetoToggle: Inverte o valor de uma propriedade

O tipo toggle alterna de 0 para 1 (Int), de True para False (Bool), de 1.0 para 0.0 (Bool) e vice-versa. Além de reiniciar propriedades do tipo Timer.

Page 262: Python BGE

BGE

Seus parâmetros são:

Prop: nome da propriedade a ser alteradaValue: valor a ser atribuído ou somado à propriedadeOB: objeto que contém a propriedade a ser copiadaProp (OB): propriedade de outro objeto a ser copiada

Page 263: Python BGE

BGE

O atuador do tipo Edit Object serve para alterar a malha de um objeto, acrescentar ou remover objetos, entre outras operações do tipo. Seus tipos são:

Add Object: adiciona uma cópia de um objeto à cenaDynamics: altera o cálculo da Física no atorEnd Object: remove o objeto da cenaReplace Mesh: troca a malha (mesh) do atorTrack To: faz o ator seguir (acompanhar) um objeto

Page 264: Python BGE

BGE

Para o tipo Add Object temos:

OB: nome do objeto a ser criadoTime: tempo de vida do novo objeto (0 = infinito)linV: velocidade linear inicial do novo objeto nos eixos X, Y e ZAngV: velocidade angular inicial do novo objeto nos eixos X, Y e Z

Page 265: Python BGE

BGE

Para o tipo Dynamics temos:

Restore Dynamics: restaura o cálculo de Física no ator (depois de suspendo)Suspend Dynamics: suspende o cálculo de Física no atorEnable Rigid Body: habilita o rigid body no atorDisable Rigid Body: desabilita o rigid body no atorSet Mass: altera a massa do ator

Page 266: Python BGE

BGE

Para o Replace Mesh temos o parâmetro ME que deve conter o nome da nova malha a ser definida para o objeto.

Para o Track To temos:

OB: nome do objeto a ser acompanhadoTime: tempo de duração do acompanhamento (0 = infinito)3D: segue o objeto nos três eixos

Page 267: Python BGE

BGE

O atuador do tipo Scene nos permite realizar alterações diretamente na cena do jogo. Seus tipos são:

Add Background Scene: adiciona uma cena atrás da cena atualAdd Overlay Scene: adiciona uma cena sobre a cena atualRemove Scene: remove uma cenaRestart: reinicia a cena atualResume Scene: continua a cena atualSuspend Scene: pausa a cena atualSet Camera: define a camera ativa para a cena atualSet Scene: define uma cena como sendo a cena atual

Page 268: Python BGE

BGE

A maioria dos tipos possui o parâmetro SCE, que é o nome da cena que se quer realizar a operação.

O tipo Camera possui o parâmetro OB que deve conter o nome da câmera a ser definida como ativa.

Page 269: Python BGE

BGE

O atuador do tipo Random serve para gerar valores aleatórios e guardá-los dentro de propriedades. Seus tipos são:

Bool Bernoulli: chance de ser verdadeiro ou falso é determinada por uma porcentagemBool Constant: sempre verdadeiro ou sempre falsoBool Uniform: 50% de chance de ser verdadeiro ou falsoFloat Constant: sempre retorna o mesmo número decimalFloat Neg Exp: o número decimal retornado é baseado num tempo de "meia-vida"Float Normal: retorna decimais baseado em uma média e um desvio

Page 270: Python BGE

BGE

Float Uniform: retorna um número decimal entre uma faixaInt Constant: retorna sempre o mesmo número inteiroInt Poisson: retorna números inteiros baseado numa médiaInt Uniform: retorna um número inteiro entre uma faixa

Os parâmetros para cada tipo são, em geral, auto-explicativos se você leu o que cada tipo faz. Todos os tipos possuem o parâmetro Seed, que é o número inicial da geração aleatória.

Page 271: Python BGE

BGE

O atuador do tipo Message serve para enviar uma mensagem a todos os atores na cena. Essas mensagens serão recebidas por um sensor do tipo Message nesses objetos. Seus parâmetros são:

To: nome do objeto para se enviar a mensagem (em branco = todos os objetos)Subject: título (assunto) da mensagem. É opcionalT/P: alterna entre enviar um texto ou o valor de uma propriedadeBody: texto da mensagemPropname: nome da propriedade cujo valor será enviado

Page 272: Python BGE

BGE

O atuador do tipo CD é usado para se controlar um CD de áudio dentro do CD-ROM. Seus tipos são:

Play all tracks: toca o CD do início ao fimPlay one track: toca apenas uma faixa específicaPause: pausa a reprodução do CDResume: retoma a reprodução do CDStop: Pára a reprodução do CDVolume: Altera o volume do áudio do CD

Novamente, os parâmetros são auto-explicativos.

Page 273: Python BGE

BGE

O atuador do tipo Game nos permite realizar operações diretamente no comportamento da BGE. Seus tipos são:

Restart this game: reinicia o jogo atualStart new game: inicia um novo jogoQuit this game: encerra o jogo atualLoad: carrega o dicionário global do disco para o jogo atualSave: salva o dicionário global do jogo atual para o disco

Page 274: Python BGE

BGE

Para o tipo Start new games temos o parâmetro File que deve conter o nome de um arquivo .blend a ser carregado e iniciado.

Os tipos Save e Load atuam sobre um dicionário global, que é nada mais do que o "estado" da BGE. É a mesma coisa que as funções de salvar e carregar dos jogos.

O dicionário é salvo como NomeDoJogo.bgeconf na mesma pasta em que está o .blend do jogo.

Page 275: Python BGE

BGE

O atuador do tipo Visibility serve para alterar a visibilidade do ator. Seus parâmetros são:

Visible: torna o ator visível ou invisível (botão desativado)Occlusion: faz com que os objetos atrás do ator não sejam visíveisChildren: aplica o atuador aos objetos que tiverem parent com o ator.

Page 276: Python BGE

BGE

O atuador do tipo 2D Filter aplica filtros gráficos ao ator. Seus tipos são:

Blur: desfoca o objetoCustom Filter: permite ao usuário usar um filtro próprioDilation: aumenta áreas mas clarasDisable Filter: desabilita (mas não remove) um filtro com o número de passos especificadoEnable Filter: habilita um filtro com o mesmo número de passos especificadoErosion: aumenta áreas mais escurasGrayScale: remove todas as cores, deixando apenas tons de cinza

Page 277: Python BGE

BGE

Invert: inverte as cores e intensidade das luzesLaplacian: destaca regiões onde ocorrem mudanças rápidas e intensasMotion blur: desfoca quando o ator se movePrewitt: calcula a orientação (rotação) local das arestas (edges)Remove filter: remove um filtro com o mesmo número de passos especificadoSepia: converte todas as cores em tons de amarelo e marromSharpen: aumenta o contraste entre pixels (nitidez)Sobel: calcula o gradiente da intensidade da imagem

Page 278: Python BGE

BGE

Todos os filtros possuem o número de passos (Pass Number), que em resumo é a qualidade do filtro. Quanto maior o número de passos, mais vezes o mesmo cálculo será feito para aquele filtro.

No tipo Custom Filter, deve-se especificar o nome de um arquivo ".py" que esteja carregado no Text Editor.

Page 279: Python BGE

BGE

O atuador do tipo Parent nos permite tornar o ator "filho" de outro objeto na cena ou remover essa relação. Seus tipos são:

Remove Parent: remove a ligação parent entre o ator e o objetoSet Parent: define outro objeto na cena como parent (pai) do ator

O parâmetro Compound adiciona a forma do filho à forma do pai. Para que funcione, os bounds de ambos devem ser do tipo Compound. O parâmetro Ghost torna o objeto insensível a colisões enquanto o parent estiver ativo.

Page 280: Python BGE

BGE

O atuador do tipo State serve para alterar o estado (state) do ator. Seus tipos são:

Add: ativa os states selecionados e não altera os demaisCpy: ativa os states selecionados e desativa os demaisInv: se os states selecionados estiverem ativos, os desativa e vice-versaSub: desativa os states selecionados e não altera os demais

Page 281: Python BGE

BGE

O sistema de states da BGE foi criado para agrupar blocos de lógica dentro de estados específicos. Por exemplo: nosso personagem pode se comportar de maneiras diferentes dentro da água, andando sobre gelo ou em terra firme, certo?

Nesse caso, devemos criar um state para cada um desses comportamentos. Dê uma olhada no controlador abaixo:

Page 282: Python BGE

BGE

O controlador mostrado possui um controlador do tipo AND no state número 1. Isso é representado pelo círculo semi-transparente. Se selecionarmos o estado número 2 e adicionarmos um novo controlador, ficaria assim:

Agora esse controlador trabalha em dois states diferentes (círculos semi-transparentes), sendo que estamos visualizando o state número 2 (selecionado). Também é possível ver o state atual ao lado do botão com o ícone da estrela.

Page 283: Python BGE

BGE

Um exemplo simples usando o cubo padrão:

O state marcado com o círculo preto é state inicial. Para fazer isso, segure Ctrl e clique nele.

Page 284: Python BGE

BGE

No state número 1 temos:

Aqui o sensor para a barra de espaços torna o ator invisível e ativa o state número 2.

Page 285: Python BGE

BGE

No state número 2 temos:

Aqui o sensor para a barra de espaços irá deixar o ator visível e ativar o state número 1. Temos um ciclo que nos permite alterar a visibilidade do ator teclando a barra de espaços.

Page 286: Python BGE

BGE

Seguindo adiante, vamos aprender um pouco sobre os módulos da BGE. Para fazer isso, configure o cubo padrão assim:

Note que o nome "meuScript.py" é válido, pois ele existe no Text Editor (parte superior da imagem). Também é uma boa ativar os botões mostrados na imagem no Text Editor.

Page 287: Python BGE

BGE

A BGE nos oferece cinco módulos principais:

GameKeys: trata as teclas do tecladoGameLogic: módulo principal das funções da BGEMathutils: funções matemáticas úteis à BGEPhysicsContraints: trata a Física da BGE diretamenteRasterizer: trata a renderização em tempo real

O módulo que mais iremos utilizar será o GameLogic. É uma boa ter sempre uma referência sobre os módulos. Eu utilizo essa: http://www.tutorialsforblender3d.com/GameFunctions/ClassIndex_1.html

Page 288: Python BGE

BGE

No guia de referência podem ser encontrados todos os módulos e classes da BGE, bem como suas funções e variáveis em detalhes. Isso é muito útil caso surja alguma dúvida.

O básico do script para a BGE é o seguinte:

import GameLogic as g

cont = g.getCurrentController()obj = cont.owner

Page 289: Python BGE

BGE

No exemplo, importamos o módulo GameLogic com o apelido de "g".

Em seguida, criamos uma variável (cont) que recebe o controlador atual, ou seja, o controlador no qual o script está definido. No caso do exemplo com o cubo padrão, ele seria o controlador do tipo Python chamado "cont".

Esse controlador é do tipo SCA_PythonContoller (consulte a referência) e possui a variável 'owner', que retorna o ator (objeto) que possui o controlador. No caso, atribuímos seu valor (objeto OBCube) a uma variável (obj).

Page 290: Python BGE

BGE

Simplificando:

Importamos o módulo GameLogicApelidamos o módulo como "g"Capturamos o controlador ("cont") que está chamando o script ("meuScript.py")Capturamos o objeto ("OBCube") ao qual o controlador ("cont") pertence.

O nome de um objeto na BGE sempre deve ser precedido por "OB". Se no Blender ele se chama "Cube", na BGE irá se chamar "OBCube".

Page 291: Python BGE

BGE

É muito importante que entenda esse script básico, portanto se ainda tem alguma dúvida, volte um pouco e não continue até entender o funcionamento do script.

Vamos complicar as coisas um pouco mais, configure o cubo assim:

Note que dei o nome "movimento" ao atuador Motion.

Page 292: Python BGE

BGE

Continuando nosso script:

import GameLogic as g

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']

O objeto 'cont' (tipo SCA_PythonController) tem a propriedade 'actuators', que contém todos os atuadores conectados ao controlador pelos blocos de lógica.

O que fizemos, foi definir à variável 'mov' o valor dessa variável no índice 'movimento', ou seja, agora 'mov' contém nosso controlador do tipo Motion chamado "movimento".

Page 293: Python BGE

BGE

import GameLogic as g

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']mov.dLoc = [0, 0.02, 0]cont.activate(mov)

Assim, é possível acessar a variável 'dLoc' do objeto 'mov' e atribuir um valor a ela, o que seria o mesmo que definir o valor de 'Loc' no bloco de lógica 'movimento'.

Finalmente, chamamos o método 'activate' do controlador que ativa o atuador, ou seja, envia um sinal verdadeiro a ele. O resultado é que ele é executado.

Page 294: Python BGE

BGE

Complicando um pouco mais:

Note que dei o nome de 'espaco' ao sensor do tipo Keyboard configurado para detectar a barra de espaços.

Page 295: Python BGE

BGE

Logo:

import GameLogic as g

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']esp = cont.sensors['espaco']

Assim como a propriedade 'actuators', temos a propriedade 'sensors', que contém todos os sensores conectados ao controlador nos blocos de lógica.

No exemplo, capturamos o sensor 'teclado' e o atribuímos à variável 'esp'.

Page 296: Python BGE

BGE

Como o sensor do tipo Always faz com que nosso script seja executado o tempo todo, logo nosso cubo irá se mover o tempo todo. Para movê-lo apenas quando a barra de espaços for pressionada, podemos fazer:

import GameLogic as g

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']esp = cont.sensors['espaco']

if esp.positive:mov.dLoc = [0, 0.02, 0]cont.activate(mov)else:cont.deactivate(mov)

Page 297: Python BGE

BGE

Aqui utilizamos a variável 'positive' que todo sensor possui para saber se ele está ativo.

Colocamos seu valor em teste dentro de uma condição ('if'). Se o sensor for positivo (verdadeiro), então movemos o cubo, caso contrário desativamos o atuador ('deactivate').

Page 298: Python BGE

BGE

Algumas mudanças:

Note que alterei o nome do sensor do tipo Keyboard para "teclado" e ativei o All keys, que irá ativar o sensor sempre que qualquer tecla for pressionada.

Page 299: Python BGE

BGE

Como o nome do sensor mudou, também é preciso alterar o script:

import GameLogic as g

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']teclado = cont.sensors['teclado']

A idéia aqui é tratar as setas de direção, fazendo com que o cubo se mova de acordo com a tecla pressionada.

Page 300: Python BGE

BGE

Para facilitar, vamos importar o módulo GameKeys:

import GameLogic as gimport GameKeys as k

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']teclado = cont.sensors['espaco']

Agora iremos utilizar a função 'getKeyStatus', que retorna o código de status de uma determinada tecla. O módulo GameKeys nos ajudará na hora de dizer a tecla desejada. Os códigos de retorno que queremos são 1 (tecla recém-pressionada) e 2 (tecla segurada).

Page 301: Python BGE

BGE

Portanto:

import GameLogic as gimport GameKeys as k

cont = g.getCurrentController()obj = cont.ownermov = cont.actuators['movimento']teclado = cont.sensors['teclado']

if teclado.getKeyStatus(k.UPARROWKEY) in [1, 2]:mov.dLoc = [0, 0.02, 0]cont.activate(mov)elif teclado.getKeyStatus(k.DOWNARROWKEY) in [1, 2]:mov.dLoc = [0, -0.02, 0]cont.activate(mov)elif teclado.getKeyStatus(k.LEFTARROWKEY) in [1, 2]:mov.dLoc = [-0.02, 0, 0]cont.activate(mov)

continua...

Page 302: Python BGE

BGE

elif teclado.getKeyStatus(k.RIGHTARROWKEY) in [1, 2]:mov.dLoc = [0.02, 0, 0]cont.activate(mov)else:cont.deactivate(mov)

Com isso conseguimos tratar as setas do teclado. Note que comparamos o retorno da função 'getKeyStatus' com uma lista, de forma que se o retorno for algum dos valores da lista, a condição retorna verdadeiro.

Note também que o valor do 'dLoc' do atuador muda de acordo com cada caso.

Page 303: Python BGE

BGE

Vamos criar uma propriedade chamada "tecla", do tipo String e com o D (debug) marcado para o cubo:

Podemos acessar essa propriedade no nosso código também, mas para facilitar, vá até o menu Game e clique em "Show Debug Properties". Assim o valor dessa variável irá aparecer o canto superior esquerdo da tela enquanto o jogo estiver sendo executado.

Page 304: Python BGE

BGE

Altere o trecho que trata cada tecla para que fique assim:

if teclado.getKeyStatus(k.UPARROWKEY) in [1, 2]:mov.dLoc = [0, 0.02, 0]cont.activate(mov)obj.tecla = 'PARA CIMA'elif teclado.getKeyStatus(k.DOWNARROWKEY) in [1, 2]:mov.dLoc = [0, -0.02, 0]cont.activate(mov)obj.tecla = 'PARA BAIXO'elif teclado.getKeyStatus(k.LEFTARROWKEY) in [1, 2]:mov.dLoc = [-0.02, 0, 0]cont.activate(mov)obj.tecla = 'PARA A ESQUERDA'elif teclado.getKeyStatus(k.RIGHTARROWKEY) in [1, 2]:mov.dLoc = [0.02, 0, 0]cont.activate(mov)obj.tecla = 'PARA A DIREITA'else:cont.deactivate(mov)obj.tecla = None

Page 305: Python BGE

BGE

No exemplo, atribuímos um valor diferente para a propriedade 'tecla' do objeto 'OBCube' de acordo com cada caso.

Quando não há uma tecla das que tratamos sendo pressionada, o valor é nulo (None).

Page 306: Python BGE

BGE

Por hora, isso é o básico que você deve saber sobre o desenvolvimento de scripts para a BGE.

Com tudo isso (e ainda há MUITO mais), você já deve ser capaz de criar bons games com Python + BGE, usando banco de dados.

Espero que esse material tenha sido de alguma utilidade para você. Qualquer dúvida, sempre existe o fórum do Blender Brasil.