Este é o primeiro post de uma série falando sobre desenvolvimento de jogos com Panda3D (versão 1.6).
Minha idéia é uma introdução sobre desenvolvimento de jogos, e eu escolhi o Panda3D como game engine, porque é um ótimo software, livre e multi-plataforma.
Antes de começar a seguir esses tutoriais, você precisa baixar uns arquivos, e seguir umas instruções para organizar as pastas dos arquivos. Acesse aqui.
O objetivo desse tutorial é fazer um jogo super simples: Uma garota, em um cenário futurista, tem que passar por umas barreiras e armadilhas.
Bueno… espero que vc já tenha o Panda3D 1.6.2 instalado, caso contrário, acesse www.panda3d.org e instale-o.
… vamos começar.
Para começar a escrever código do Panda3D, você precisa de um editor de texto simples, Microsoft Word ou Open Office Writer não servem!
Caso você trabalhe com Linux, Gedit é muito bom!
Caso você trabalhe com Mac, Xcode até dá… mas não é o melhor…
Caso você trabalhe com Windows, tente o Notepad++
Mas para todos eu sugiro o Eclipse com plugin de python (você pode usar o Eclipse for PHP), ele é um pouco difícil de configurar, mas vale o esforço.
Com tudo pronto, vamos digitar um código. Comece um novo arquivo, nomeie-o como Panda-tut-00.py, e vamos colocar o seguinte código:
[code lang=”python”]
import direct.directbase.DirectStart
run()
[/code]
Esse é o código mais simples que podemos fazer e ter o Panda3D funcionando!
A primeira linha importa a classe DirectStart, que define algumas configurações e inicia o sistema do Panda3D.
A linha run(), basicamente inicia o ‘main loop’ do Panda3D. Todo jogo precisa de um ‘main loop’. O main loop, é a mágica que nos fornece o “Frame”! Graças aos “frame por segundo”, podemos mudar o posicionamento dos objetos do jogo, durante o tempo, e assim a mágica acontece.
Para executar esse código, você precisa:
Caso você trabalhe com Linux (você já sabe oq fazer, eu sei…), navegue pelo Terminal até a pasta Panda-project/src, e execute: python Panda-tut-00.py
Caso você trabalhe com Mac (eu acho que você sabe oq fazer…), navegue pelo Terminal até a pasta Panda-project/src, e execute: python Panda-tut-00.py
Caso você trabalhe com Windows (ohh… Deus, que o Senhor tenha piedade de sua alma!)… Você precisará lembrar como navegar pelas pastas do seu sistema pelo Prompt de Comando, usando o comando ‘cd’. Para abrir o prompt de commando, vá ao menu iniciar, e na pesquisa digite “command”, e então navegue até a pasta Panda-project/src, e execute: python Panda-tut-00.py
Esse é o processo de como rodar as todos os códigos feitos para o Panda3D, decore!
Ok… vamos começar de verdade!
Vamos a um código de verdade, o anterior foi só para preparar alguma base. Vamos carregar para o jogo uma arena, e um plano de fundo:
[code lang=”python”]
from pandac.PandaModules import loadPrcFileData
loadPrcFileData(”,’show-frame-rate-meter 1′)
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
#game class
class Game(DirectObject):
def __init__(self):
#load platform model
self.plataforma = loader.loadModel(“../assets/eggs/plataformaBase”)
self.plataforma.reparentTo(render)
self.plataforma.setPos(0,10,0)
#load background sky
self.wall = loader.loadModel(‘../assets/eggs/papelParede’)
self.wall.reparentTo(render)
self.wall.setScale(1)
self.wall.setPos(-5, 30, -2)
game = Game()
run()
[/code]
Ao rodar o programa você verá algo assim:
LEMBRANDO: Isto é um código para computadores, nenhum erro de digitação é tolerado. Uma única letra errada, causará um erro. Outro erro bem comum é quando o Panda3D não encontra os arquivos que estamos carregando para o jogo, isso geralmente acontece se vc digitar o endereço dos arquivos errado, ou se não organizou os arquivos de forma correta… dá uma lida aqui.
O que nós fizemos:
1 – Tá vendo aquele número no canto superior direito da tela? São nossos frames por segundo! essas duas primeiras linhas são responsáveis por ele aparecer alí:
[code lang=”python”]
from pandac.PandaModules import loadPrcFileData
loadPrcFileData(”,’show-frame-rate-meter 1′)
[/code]
2 – Agora pedimos ao Panda3D, algumas das ferramentas que ele tem disponível para trabalhar. O Panda3D, é um conjunto de muitas ferramentas para desenvolvimento de games, e não precisamos de todas a todo momento, então pedimos essas ferramentas na medida que as usamos:
[code lang=”python”]
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
[/code]
3 – Como somos pessoas do bem, criaremos nosso jogo com “programação orientada a objetos”, isso quer dizer que cada objeto de nosso jogo será criado com um conjunto de código separado dos outros. E para começar, nossa própria lógica do jogo será um objeto em sí, e escreveremos uma classe para ela:
[code lang=”python”]
class Game(DirectObject):
def __init__(self):
self.platforma = loader.loadModel(“../assets/eggs/plataformaBase”)
self.platforma.reparentTo(render)
self.platforma.setPos(0,10,0)
self.wall = loader.loadModel(‘../assets/eggs/papelParede’)
self.wall.reparentTo(render)
self.wall.setScale(1)
self.wall.setPos(-5, 30, -2)
[/code]
4 – Finalmente, instanciamos nossa classe do jogo, e executamos o main loop:
[code lang=”python”]
game = Game()
run()
[/code]
Ponto crucial
Nesse momento vamos falar sobre o que esta acontecendo dentro da classe Game. A classe Game é inicializada na função def __init__(self):
Esse função é executada uma única vez quando o objeto é instanciado(trocando em miúdos, quando ele é criado), e nessa função nós mandamos o Panda3D configurar alguns elementos do jogo: a arena e o plano de fundo. Vejamos o exemplo da plataforma.
Primeiramente pedimos ao Panda3D para importar o modelo “plataformaBase”, e armazenar o ‘caminho’ para esse modelo na variável self.plataforma.
Porque esse é um ponto crucial?? Primeiro porque esse é o passo mais básico para carregar qualquer modelo para sua cena, mas mais importante que isso, precisamos entender esse tal de “render”.
O “render” é o nó raiz do grafo de cena do Panda3D! Essa explicação foi suficiente pra você? Ótimo! Pule para o próximo capítulo. Se a definição não lhe serviu, preste atenção na explicação.
Primeiro, o que é um grafo de cena? Um grafo de cena é uma forma estruturada de se organizar elementos em um ambiente gráfico.
Quase todos os softwares gráficos que conheço usam um grafo de cena. Basicamente um grafo de cena, possui um ‘nó’ principal, que aponta para outros elementos que apareceram na cena. Essa forma estruturada serve para otimizar trabalho do sistema de renderização, comunicação entre objetos da cena, collisões, etc… Dê uma olhada nesse link, e nesse também!
Qualquer objeto que tenha que aparecer na cena, precisa estar lincado, direta ou indiretamente ao grafo de cena. Um objeto pode se linkar ao gafo diretamente, ou a outro objeto que já esteja linkado.
Cada elemento adicionado ao grafo de cena, temos um nó (node) e um caminho (nodepath). O nó é criado no grafo de cena, e o caminho para o nó (nodepath), é alocado na variável do código python. ‘Nós’ e ‘caminho de nós’ (nodepaths), não são a mesma coisa, mas no Panda3D, nodepaths são muito mais usados do que os nós propriamente ditos. Então, quando o código diz: self.plataforma = load.loadModel(“../assets/eggs/plataformaBase”), o Panda3D, carrega o modelo 3D, cria um nó para o grafo de cena, salva o nodepath na variável self.plataforma.
Posteriormente, para que o objeto seja visível, é necessário linkar seu nó, ao ‘render’: self.plataforma.reparentTo(render).
Bem, o render é o nó principal desse grafo de cena, logo é o centro, o ponto de origem do sistema de coordenadas do Panda3D. Então, após importar o modelo, e linkar ao grafo, podemos posicioná-lo na cena: self.plataforma.setPos(0,10,0)
Esse processo se repetirá por todos os elementos que quisermos colocá-lo na cena. Então ao fim desse código teremos, uma estrutura com essa aparência:
SUGESTÃO: brinque com as posições dos objetos, e com seus links:
– altere os valores das cooredenadas tanto da plataforma, quanto do wall, para entender melhor os valores;
– link o wall, à plataforma: self.wall.reparentTo(self.plataforma);
– brinque com as coordenadas;
– linke a plataforma ao wall, e modifique as coordenadas.
Isso lhe ajudará a entender melhor essas coisas no Panda3D.
This is the first post about game development in Panda3D. (version 1.6)
My idea is to introduce people in game development, I have chosen Panda3D as game engine, because it is a great software, free and multi-platform.
In order to start following these tutorials, you will need to download some files, and follow some instructions about how organize the files. Here is the link.
The goal here is to build a very simple game: A girl, in a futuristic scenario, who needs to avoid some barriers and traps.
I hope you already have Panda3D 1.6.2, otherwise, go to www.panda3d.org, download and install it. (There is some issue with MacOSX version, check forum to find solutions)
… let’s start.
To start writing Panda3D code all you need is a simple text editor, Microsoft Word or Open Office Writer do not work for this!
In case you work on Linux, Gedit is great!
In case you work on Mac, Xcode is… is ok, but…
In case you work on Windows, you should try Notepad++
But for all, I suggest Eclipse with python plugin (you can download Eclipse for PHP), it is a bit hard to setup, but it worth the effort.
So… if you are ready, let’s go and write some code. Start a new file, we could name it as Panda-tut-00.py, and write the following code:
[code lang=”python”]
import direct.directbase.DirectStart
run()
[/code]
This is the most simple code we can write to test if Panda3D is working!
The first line imports the DirectStart class, that starts Panda3D basic systems, and creates the screen where our game is gonna happened.
The line run(), basically starts the Panda3D main loop. Every game needs a main loop. The main loop, is a magical stuff that will give our game the “Frames”! And thanks for the frames per second, we can change game objects position in time, and all the magic is possible.
In order to run this simple code you have to:
In case you work on Linux (you know what to do, but…), you go to the Terminal, navigate to Panda-project/src folder, and run: python Panda-tut-00.py
In case you work on Mac (I think you know what to do…), you go to the Terminal, navigate to Panda-project/src folder, and run: python Panda-tut-00.py
In case you work on Windows (ohh… dear Lord, that God have mercy of your soul!)… You need to remember how to navigate using the Command Prompt, and the command ‘cd’. To start Command Prompt, go to Start menu >> All Programs >> Accessories >> Command Prompt, and navigate till the Panda-project/src folder, and run the command: python Panda-tut-00.py
…and that’s how you are gonna run and test, all our codes! You must know this process by heart!
Ok… let’s start for real!
Let’s start a real code… the previous was just to lay down some basis. Let’s start loading our scenario, our arena:
[code lang=”python”]
from pandac.PandaModules import loadPrcFileData
loadPrcFileData(”,’show-frame-rate-meter 1′)
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
#game class
class Game(DirectObject):
def __init__(self):
#load platform model
self.platform = loader.loadModel(“../assets/eggs/plataformaBase”)
self.platform.reparentTo(render)
self.platform.setPos(0,10,0)
#load background sky
self.wall = loader.loadModel(‘../assets/eggs/papelParede’)
self.wall.reparentTo(render)
self.wall.setScale(1)
self.wall.setPos(-5, 30, -2)
game = Game()
run()
[/code]
After running this code, you should see some thing like this:
JUST TO REMEMBER: this is a computer code, so, none errors in typing are tolerated. One single wrong letter, might cause an error. Also, another common error occurs when Panda3D do not find the models, we are asking him to bring to the game! So… follow the instructions here.
Let’s see what we have done:
1 – Are you seeing that little number on top-right corner? Those are your frames per second! and the first two lines are responsible for it to appear:
[code lang=”python”]
from pandac.PandaModules import loadPrcFileData
loadPrcFileData(”,’show-frame-rate-meter 1′)
[/code]
2 – Now we need to inform Panda3D, which “parts” of it we need for the job. Panda3D is very big tool, and we don’t need all of it’s parts all the time… so we are asking it to give us some of it’s tools:
[code lang=”python”]
import direct.directbase.DirectStart
from pandac.PandaModules import *
from direct.task.Task import Task
from direct.showbase.DirectObject import DirectObject
[/code]
3 – As we are good people, we will create our code using object oriented programming, it means that all our game objects will be created in deferent parts of code. To start with our own game logic, will be and object itself, for that we define a class for it:
[code lang=”python”]
class Game(DirectObject):
def __init__(self):
self.platform = loader.loadModel(“../assets/eggs/plataformaBase”)
self.platform.reparentTo(render)
self.platform.setPos(0,10,0)
self.wall = loader.loadModel(‘../assets/eggs/papelParede’)
self.wall.reparentTo(render)
self.wall.setScale(1)
self.wall.setPos(-5, 30, -2)
[/code]
4 – We must instantiate our game class, into an object, and run it:
[code lang=”python”]
game = Game()
run()
[/code]
Crucial point
At this point we must talk about what is going on inside the class Game. The Game class has an initialize function def __init__(self):
This function is called once when the object is been instantiated, so inside this function, we write all the code we need to set up or game object. At the moment, we just brought to the game our arena and a background. Let’s watch the self.platform.
First we tell Panda3D to load the “plataformaBase” model, and put it’s path into self.platform variable. Than, we reparent the platform to the ‘render’, and finally we give platform a position.
Why this is a crucial point? First because this is the basic step, to load whatever you want into the game. But above that, we must understand what is this ‘render’?
The ‘render’ object is Panda3D scene graph’s top node! Was that explanation enough for you? Greate! Skip to the next chapter. If that definition wasn’t enough for you, pay attention to the explanation.
First of all, what is a scene graph? A scene graph is a structure to organize hierarchically the elements of a scene.
Almost all graphic softwares I know use a scene graph. Basically a scene graph starts with a main object, which points to other objects that are included into the scene. Such structure is used to optimize rendering processes, comunications among elements, collisions, etc. Take a look at this link, and this one!
Basically any object we want to appear in the game scene, must be some how linked to the scene graph. This object can be linked straight to the “render” node, or linked to an object which must be linked to “render”.
Each element we add to the scene graph, we create a Node and a NodePath. The node is created into the scene graph, and the path to this node (nodepath) is stored into a variable we name, in python code. Node and nodepaths, are not the same thing, but in Panda3D, nodepaths are much more used than the node itself. So, when the code says : self.platform = loader.loadModel(“../assets/eggs/plataformaBase”), Panda3D, loads a model, and creates a scene graph node, and save a path to this node in the self.platform variable.
Latter, in order to make this model visable, it’s necessary to link this new node to the render: self.platform.reparentTo(render).
Well, the “render” is the top node on Panda3D scene graph, and it is the center, the origin point of Panda3D’s coordinates system. So, after having the model imported, and linked to the scene graph, we can set a position to it: self.platform.setPos(0,10,0)
This process is repeated to all objects we want to insert into the scene. At the end of this process, we will have a scene graph estructure like this:
ADVICE: mass around with object’s position, and it’s links:
– change the coordinates values in platform and wall objects;
– link the wall, to the platform: self.wallreparentTo(self.plataforma);
– change the coordinates again;
– link the platform to the wall, and change the coordinates again.
This will help you to understand better this subject in Panda3D.