Ponto V!

Home Arquitetura Programação Funcionamento de um jogo - Objetos do Jogo
Bruno Crivelari Sanches
Funcionamento de um jogo - Objetos do JogoImprimir
Escrito por Bruno Crivelari Sanches
Índice do Artigo
Funcionamento de um jogo
Objetos do Jogo
Rede
Todas Páginas

Objetos do Jogo

Os objetos do jogo (ou game objects) são a parte do código que cuidam de dar vida ao jogo, podendo representar inimigos, portas, elevadores, etc. Esses objetos podem ser representados das mais variadas formas, indo aos primórdios, um jogo no estilo Space Invaders poderia simplesmente ter uma lista de estruturas no formato:

struct Ship
{
    int x, y;
    int movement_type;
    int life;
    int shooting_rate;
};

Ship enemies[MAX_ENEMIES];

Onde uma nave possui apenas sua posição x e y na tela, um inteiro indicando o tipo de movimento que esta realiza, um outro inteiro com a energia desta e por fim um inteiro que diz quantas vezes ela atira (que pode ser por segundo, minuto, fica a cargo do programador).

Conforme os jogos foram aumentando de complexidade e com a popularização da programação orientada a objetos este conceito foi evoluindo e temos uma estrutura no estilo:

// Map Object definition.
typedef struct mobj_s
{
    // List: thinker links.
    thinker_t        thinker;

    // Info for drawing: position.
    fixed_t        x, y, z;

        //More drawing info: to determine current sprite.
    angle_t        angle;    // orientation
    spritenum_t        sprite;    // used to find patch_t and flip value
    int            frame;    // might be ORed with FF_FULLBRIGHT

    // For movement checking.
    fixed_t        radius, height;

    // Momentums, used to update position.
    fixed_t        momx, momy, momz;

    mobjtype_t        type;
    mobjinfo_t*        info;    // &mobjinfo[mobj->type]
    
    int            tics;    // state tic counter
    state_t*        state;
    int            flags;
    int            health;

    // Movement direction, movement generation (zig-zagging).
    int            movedir;    // 0-7
    int            movecount;    // when 0, select a new dir        
} mobj_t;

A estrutura acima foi tirada do jogo Doom (que possui código aberto, o código pode se baixado clicando-se aqui). Esta estrutura, chamada de mobj_t (map object ou objeto do mapa) é apresentada aqui com alguns cortes (cheque o fonte para a versão completa). O interessante é que essa estrutura é usada para os mais diversos objetos do jogo, desde inimigos a portas, elevadores, etc. Sendo assim, podemos ver que ela não é muito diferente da estrutura anterior, mas possui algumas diferenças fundamentais.

O primeiro item é o thinker (que é o primeiro atributo), este é uma outra estrutura que armazena um ponteiro para função e outros dados. Esse ponteiro para função varia de acordo com o tipo de objeto sendo representado e o estado do mesmo. Por exemplo, no caso de uma porta, este ponteiro pode apontar para a função que cuida de movimentar ela, temos aqui então um principio de polimorfismo.

Depois temos variáveis que cuidam da posição do objeto, informações para desenho, controle de movimentação, etc, e temos novamente outro ponto de interesse que é a variável type, que é um enum que diz que tipo de objeto uma instância dessa estrutura representa, e o atributo info, que contêm informações especificas para cada tipo (na verdade no caso do Doom ele representa uma maquina de estados).

Outros jogos já costuma usar uma hierarquia de classes, como o exemplo a seguir:

uml_game

Jogos como Unreal, Half-Life, etc, usam esse tipo de sistema. Essa estrutura funciona muito bem, mas tem alguns problemas, um exemplo clássico (ou problema clássico) é de um rpg onde a classe ator implementa toda a parte de conversação e em um determinado ponto do jogo é preciso que uma porta converse com o jogador! Como resolver? O jeito mais simples é mover o código de conversação para uma classe comum entro todas, mas isto na maioria das vezes acaba causando um inchamento da classe base.

Devido a problemas desse tipo atualmente a industria tem adotado cada vez mais uma organização de objetos do jogo em forma de componentes, como demonstrado na figura abaixo:

umg_game_comp

Nesta estrutura temos um gerenciador de componentes e 5 tipos de componentes:

  • Position; que posiciona objetos no cenário
  • Movement: que cuida de movimentar objetos
  • Ridig Body: que representa um corpo rígido usado em sistemas de física.
  • 3d Object: que é o objeto 3d que vemos na tela
  • AI: que cuida da inteligência artificial.

Agora os objetos do jogo ao invés de estarem dentro de uma hierarquia vão ser todos formados por um único tipo (semelhante ao mobj do Doom), mas cada um vai ter uma coleção de componentes, sendo que componentes vão sendo adicionados para se formar um objeto, como a árvore que possui apenas “Position”, “Rigid Body” (para colisões) e “3d Object”, ou o Item life que possui apenas os componentes de posição e objeto 3d. Esse tipo de estrutura costuma ser muito flexível, mas trás algumas dificuldades sobre como armazenar os componentes, como tratar dependências, etc.

Dando Vida ao Jogo

Sabendo como organizar os objetos de um jogo vamos ver então como eles criam vida própria. A maneira mais simples de se realizar essa operação é usando um método update, supondo que independente da forma de organização que foi usada temos uma classe base com esse método, podemos então:

void updateGame(float delta)
{
    foreach(GameObject obj in gameObjects)
    {
        obj->update(delta);
    }
}

Novamente temos nosso pseudo código, que percorre a lista de objetos avisando cada um que é hora dele se movimentar. Um detalhe importante é que para fazer o jogo funcionar na realidade não é preciso utilizar threads (ao contrário do que muitos iniciantes pensam), o que importa mesmo é que todos os objetos sejam atualizados todo quadro. Sendo assim, eles são atualizados de forma sequencial, mas o resultado é visto apenas quando o frame é desenhado, dando sensação de que tudo ocorreu ao mesmo tempo.

Atualmente com a popularização de processados de múltiplos núcleos os jogos estão começando a recorrer ao uso de threads, pois sem o uso destas não é possível utilizar todo o potencial dos processadores modernos. Devido a alta acoplagem que é comum entre objetos de um jogo é incomum a atualização desses ser multithread, então para compensar isto tem se dividido o motor de jogo em varias threads, sendo uma arquitetura comum termos uma thread para desenho 3d, uma para gameplay, uma para física e outra para inteligência artificial. Como muitos recursos utilizados pelos objetos de jogo agora são feitas em threads, têm se tornado comum também o uso de operações assíncronas (onde quando um objeto pede um teste de colisão, ele pode obter resposta apenas em um quadro futuro).

Linhas do Tempo

Com o aumento da complexidade dos jogos os motores tem se modularizado cada vez mais, sendo assim é comum termos módulos que cuidam apenas de partes especificas do jogo, como animação, fisíca, inteligência artificial, etc. Nesse contexto, os objetos do jogo ficam apenas com a tarefa de juntar tudo isso.

Vamos imaginar um npc que decide caminhar até um ponto do cenário: O sistema de inteligência artificial decide que o NPC deve se deslocar (ou um evento do jogo da essa ordem ao NPC). O NPC vai então requisitar ao sistema de IA que encontre um caminho até seu destino, o sistema de IA então calcula a rota e devolve ao NPC. O NPC então requisita ao sistema de movimentação do jogo que se desloque até ao ponto de destino, informando a esse qual a velocidade máxima do NPC, aceleração, etc. Ao mesmo tempo o NPC solicita ao sistema de animação do jogo que inicie a animação de andar do NPC, agora o NPC entra num estado de hibernação até que alguem lhe avise que ele chegou ao destino.

O interessante desse exemplo é que o NPC não precisa ser atualizado todo quadro, pois ele não faz nada além de dar ordens. Os sistemas que ele invocou (animação, movimentação, etc) precisam ser atualizados o tempo todo para manter a movimentação dos modelos. Sendo assim é comum em jogos modernos que a lógica o jogo rode em uma taxa fixa, por exemplo 10 frames por segundo (que era o número utilizado por todos os Quakes, por exemplo). Já o sistema de animação precisa ser atualizado toda vez que algo vai ser mostrado na tela. O sistema de física por outro lado precisa ser atualizado com a maior frequência possível, a maioria dos motores de física exigem que suas atualizações ocorram no minímo 60 vezes por segundo. O sistema de IA geralmente possui uma taxa de quadros baixa, ficando em torno de 10 quadros.

Assim, vemos que um jogo pode ter frequências de atualizações bem diferentes para cada módulo, um caso tipico:

  • Objetos do jogo: 10 quadros
  • Inteligência artificial: 10 quadros
  • Animações: variável, atualizado sempre que o vídeo é desenhado
  • Física: 60 quadros


Comentários (51)
  • Vitor Almeida da Silva  - Muito bacana
    avatar

    Muito bacana o artigo.

    É sempre importante comentar sobre as diferenças entre abordagens diferentes (no caso as arquiteturas) pra poder saber os prós e contras de cada uma e usá-las (ou não) da melhor maneira possível.

    É até engraçado, mas ontem mesmo eu tinha estudado o código da estrutura (struct mobj_s
    ) do Doom do iPhone e não tinha encontrado o que significava o prefixo "mob" (nem tinha imaginado)...

  • Bruno Crivelari Sanches
    avatar

    Obrigado Vitor!

    os códigos do Doom (e da Id em geral) são uma verdadeira escola, vale muito a pena gastar um tempo fuçando eles.

    O mais interessante desses códigos é como eles usam técnicas relativamente simples para fazer tarefas que muitos acabam complicando.

    Custou para eu descobrir também de onde vinha o nome :).

  • William
    avatar

    Dever ser mobj_s = move object source

  • José Ricardo  - Excelente
    avatar

    Parabéns pelo artigo Bruno. Tenho aprendido realmente muita coisa com o site. Este seu novo artigo também está excelente.

    Valeu!!! :lol:

  • Bruno Crivelari Sanches
    avatar

    Obrigado José! É muito bom saber que as pessoas tem conseguido aprender e entender os artigos :).

  • Alan de Oliveira
    avatar

    Muito bacana o artigo.
    A propósito, qual seria o significado de mobj_s ?
    XD~ também estou curioso agora.

  • Bruno Crivelari Sanches
    avatar

    Valeu Alan!

    Esta la no texto hein o significado, não vou contar :evil: .

  • Bruno
    avatar

    Muito bom o artigo. Parabéns!
    A criação de jogos está cada vez mais interessante. Você poderia indicar alguns livros?

  • Lopídio Guigui  - Excelente artigo!
    avatar

    Ótimo artigo.
    Já fazia um tempo que eu procurava algo parecido com isso pela internet.
    Incrível, bastante esclarecedor!
    Aliás, como todo o site!

    Parabéns, vocês ganharam um fã!

  • Bruno Crivelari Sanches
    avatar

    Pessoal, muito obrigado pelos elogios! Fico feliz em saber que os artigos tem ajudado!

  • Gustavo Campos  - Ótimo artigo
    avatar

    Parabéns pelo artigo, muito bom. Cheguei até ele pois estava escrevendo sobre o auxilio dos conceitos da programação de jogos em simuladores de negócios.

  • 9-volt  - 9-volt
    avatar

    cara estou estudando Java, quem sabe qua ndo eu me desenvolver mais eu aprenda a fazer um joguinho.

  • Sora  - Muito legal!
    avatar

    Gostei muito do artigo, com certeza essas técnicas que foram mostradas vão ajudar muita gente. Parabéns! :)

  • Roberval Sena  - mais exemplos?
    avatar

    rapaizz

    eu to aqu estudando C++, e já brinco com outras linguagens... e o que fica pra mim é a falta de exemplos....

    tipo... será que existe um jogo com os códigos de cliente e servidor pra eu poder ver como é o "andar da carruagem?"?

    sabe .. brincar com algo que esteja andando.. por a mão....

    pq do zero.. nossa como dói!

    []s Sena

  • Jeison Frasson  - MMO
    avatar

    Gostei muito da postagem, mesmo por que eu já trabalhava com esse ultimo conceito de cliente executar o jogo, porem sofro de mais com LAG pois programo jogos em php + JS

    agora decidi partir para JAVA

    esse é um teste que estou fazendo em php + js para um mmoRPG

    londor3.londor.com.br

    como disse meu problema é o tempo de resposta de clientes para clientes já que fazer 60 consultas em php por segundo é homicídio de banda

    até mais

  • Fernando  - Ajuda !!! Urgente
    avatar

    Olá pessoal, tenho um cliente meio urgente, e não sei onde encontrar tal profissional, meu cliente precisa,alias quero montar um site de jogos no estilo click jogos, desenvolvemos toda a estrutura do site e funcionalidades, porem os jogos estão sendo um grande problema, são 3 jogos iniciais, jogos de carta, sinuca e poker, tudo isso com usuarios em tempo real, com chat e video conferencia nas salas vip, enfim todo o projeto esta desenvolvido e ja desenhado. Agora com relação aos jogos, ainda nao encontrei quem possa desenvolver, encontrei um programador conheci alguns de seus trabalhos mas me cobrou 3 mil reais pelo desenvolvimento dos jogos no site, um outro amigo me disse que está caro, por se tratar de jogos que na maioria das vezes ja tem pronto é so adaptar ao sistema do site, mas não conheço e me indicaram voces como sendo a melhor fonte para descobrir isso, agradeço a ajuda de quem puder me retornar essa questão, grande abraço e parabens pelo site.

  • Bruno Crivelari Sanches
    avatar

    Olá Fernando,

    por esse valor ou menos não sei de ninguém que faria.

    O desenvolvimento disso não é tão simples e mesmo tendo jogos prontos por ai não é apenas "adaptar" no site, podem surgir n problemas.

    Se o programador cobrou esse valor e garantiu que vai entregar tudo pronto com as funcionalidades que você esta pedindo, não acho caro.

    Certamente tem pessoas que fariam por bem menos, mas tem que tomar cuidado para o barato não sair caro.

  • Vinícius Godoy de Mendonça
    avatar

    Lembre-se também que na maioria das vezes você não pode simplesmente copiar o código de outro e comercializá-lo. Além de adaptações necessárias, como citou o Bruno, você poderia sofrer um problema legal, caso o criador do software resolva questionar a autoria.

    O programador, com razão, deve ter cobrado o desenvolvimento integral do software.

    Além disso, a menos que seu conteúdo seja exclusivo, você precisará também pagar pelas imagens e sons do seu jogo.

  • adailton  - manero
    avatar

    :) muito bom post eu ja suspeitava que o jogo era nada mais que muitos fps em segundos agora imagina um mmorpg como o runescape mais de 10 mil online enviando para o servidor mensagens e atualizaçoes com 60 quadros por segundo e o jogo e em browsers.

  • Bruno Crivelari Sanches
    avatar

    Obrigado Adailton!

    Apenas um detalhe: um MMORPG e geralmente qualquer outro jogo multiplayer não mantém a parte de rede rodando a 60 fps, quando muito o sistema de rede roda a 10 fps. Mas se considerarmos um ping nacional típico de 200ms, temos apenas 5 fps na parte de rede.

    T+

  • adailton  - voltei
    avatar

    cara tive quebrando a cabeça com uns mmorpg e nao consigo entender como sao feito as comunicaçoes, server e cliente.

    sera que é assim quando o cliente se move é aberto um socket com servidor e depois que foi ecoado para todos o socket é fechado?

    porque eu nao entendo com é que o servidor consegue fazer comunicaçao entre 100 clientes sustentando posiçao,imagem,level,nome etc, e nao sei onde fica armazenado essas variaveis.

    tive a ponto de fazer um com java no lado do server e javascript no lado do cliente só que nao consegui encontrar uma maneira de lidar com os sockets entre os dois.


    tentei com esse servidor java: http://jwebsocket.org/

    mas eles nao tem um passo a passo nem um helow world nem nada.

    estamos precisando de um passo a passo de como fazer isso.

  • Bruno Crivelari Sanches
    avatar

    Não, a conexão é aberta assim que você carrega o jogo. O cliente vai conectar no server, fazer autenticação, etc. Isso pode ser feito com udp ou tcp, tanto faz...

    No jogo a comunicação é feita via UDP e o socket fica aberto tempo todo. O cliente é o que chamamos de terminar burro. Quando você manda ele andar ele envia um pedido ao servidor, que movimenta ele e depois lhe manda sua nova posição.

    Claro que isso gera um lag absurdo, dai entra o que chamamos de predição ou previsão, o cliente tenta prever para onde vai mover e se movimenta, depois só confirma a posição com o servidor. Mas a autoridade é sempre o server.

  • adailton  - entendi
    avatar

    entao digamos que eu me em seu jogo e la vai ter as tabelas:

    nome = adailton

    senha = 1234

    personagem = teste

    posiçaox = 120

    posiçaoy = 250

    vou logar ai digito meu login e senha no server, e entro digamos que voce esta no jogo:

    nome = vinicíus

    personagem = vinicius

    posiçaox = 300

    posiçaoy = 400

    como que ao entrar no jogo o servidor vai lidar com esses dados tipo variavel nome, prsonagem, posiçaox, posiçaoy. e vai destinguir o seu avatar do meu? esses dados sao armazenados em variaveis? ou tem outro geito?

    ou esses dados fica no cliente tipo chat ele péga oque esta digitado nos campos nome, e mensagem, e manda para o servidor assim

    adailton mandou uma mensagem: oi

    e na sala do jogo pegaria meu nome posiçao e imagem e e enviaria para quem estivesse na sala?


  • Bruno Crivelari Sanches
    avatar

    Você esta falando de um MMO usando html? Desses jogos interativos via web? Nesse caso não tem diferença de um app web qualquer.

    E nem tem porque se preocupar com sockets, nenhum framework moderno deixa você sequer chegar perto de algo parecido com socket.

    T+

  • adailton  - javascript
    avatar

    seria na verdade java(server) html + javascript(cliente) da mesma forma do jwebsocket. no jwebsocket o socket ou seila oque é declarado em uma variavel pelo cliente assim:

    var host = "ws://localhost:8000//server";

    nao seria bem um jogo seria uma pagina na web como se fosse uma sala de jogo, onde os visitantes podessem ver oque os outros estivessem fazendo

    parecido com isso aqui: http://dkozar.com/flash/izometrija.html só que em javascript sei fazer mapa personagem e tudo só nao sei como torna-lo multplayer.

  • Bruno Crivelari Sanches
    avatar

    Nesse caso eu acho que não diferencia muito de um jogo tradicional. O básico mesmo é simplesmente transmitir a posição do personagem para o servidor e este replicar para os clientes.

    Problema é que pelo jeito websockets somente via TCP, isso pode gerar um bocado de lag.

    T+

  • Anônimo  - MUITO BOM
    avatar

    Só tenho uma coisa para dizer sobre o artigo :D e é :

    MAMA MIA :woohoo:

  • Bruno Crivelari Sanches
    avatar

    Muito obrigado! :)

  • Anônimo  - Bruno uma ajudinha
    avatar

    :) Bruno você esta on-line filho? Poderia me passar uns links sobre controle de pacotes UDP não consigo imaginar como faze-lo. Estou pensando de usar o Raknet ele ja vem com todo o controle né? Obrigado.

  • Bruno Crivelari Sanches
    avatar

    Nesse link existe uma explicação sobre como fazer com o UDP: http://gafferongames.com/networking-for-game-programmers/reliability-a nd-flow-control/

    No caso da Raknet que eu saiba a lib já cuida de tudo para você.

    T+

  • augustowebd  - calculo de delta
    avatar

    Olá Bruno,

    Em primeiro lugar eu gostaria de parabenizá-lo pelo excelnte artigo.

    Lendo o artigo eu fiquei com uma dúvida que é a seguinto: "vamos supor que temos um jogo rodando a 60 quadro por segundo, neste ritmo o valor de delta vai ser de 0,016 segundos"

    Estamos assumindo que que a diferença de tempo foi de 3,750seg?
    (delta = 3,750/60).

    Caso meu entimento esteja errado, poderia por favor me explicar?

    Grato mais uma vez.

  • Bruno Crivelari Sanches
    avatar

    Obrigado Augusto!

    Não, o tempo vai ser 1 segundo. O delta indica quanto o tempo variou entre um quadro e outro. Se temos uma taxa de 60 quadros por segundo, então temos: 1/60 = 0,1666666...

    T+

  • Anônimo  - re:
    avatar
    Bruno Crivelari Sanches Escreveu:
    Obrigado Augusto!

    Não, o tempo vai ser 1 segundo. O delta indica quanto o tempo variou entre um quadro e outro. Se temos uma taxa de 60 quadros por segundo, então temos: 1/60 = 0,1666666...

    T+

    Agora sim entendi.

    Grato!

  • Marcius  - Parabéns
    avatar

    Valeu mesmo cara, deu uma esclarecida legal nas ideias.

  • Bruno Crivelari Sanches
    avatar

    Obrigado Marcius

  • Felipe Merlim  - .
    avatar

    Bruno,você conseguiria mostrar o diagrama de classes de god of war?

  • Anônimo
    avatar

    Não tem como, não sei detalhes do código, a empresa não divulgou muita coisa.

  • Wagner  - Acessar a continuação
    avatar

    Não consigo acessar as sessões Objetos do Jogo e Rede do artigo. Gostaria que arrumassem. Grato.

  • Anônimo
    avatar

    Testando aqui e todos abriram normalmente.

    Qual navegador?

  • Wagner
    avatar

    Google Chrome Versão 23

  • Wagner
    avatar

    Agora funcionou :whistle:

  • Marcos Silva
    avatar

    Cara muito bom o artigo, tava procurando por algo assim faz um tempinho

  • Anônimo
    avatar

    Obrigado Marcos!

  • adailton  - programaçao
    avatar

    obrigado pelo belo post. :D

    como funciona as animaçoes tipo a parte do tiro eu entendi mas:

    mas se meu jogo for em fps 'frames por segundo' , tenho um avatar movendo um background com 6 imagens e para que outros players vessem eu me movendo eu teria que enviar para o servidor a posiçao do background a cada 2ms para o servidor atualizar meu movimento para outros jogadores que estão na area de visão do mapa.


    esse envio de posiçao do background nao iria derrubar meu servidor?

    exemplo; tenho um loop for correndo em um background que faz animaçao do avatar eu envio todas aquelas animaçoes para o servidor em tao pouco tempo?

  • Anônimo
    avatar

    Você não precisa enviar tudo ao servidor, o servidor já sabe as propriedades do seu avatar, idem para animação.

    Se ele esta andando, o servidor já sabe que tem que rodar a animação dele andando e os outros clientes também, não precisam saber mais nada.

    A mesma coisa é o background, se o servidor sabe que você andou, sabe que tudo mudou.

  • Jadson
    avatar

    Muito informativo. Parabéns!
    (A propósito, apesar de ver perfis com avatar, não achei onde me registrar no site. É possível? rs)

  • Anônimo
    avatar

    Oi Jadson, registro hoje só para autores. Não existe nada especifico para leitores :).

  • michel
    avatar

    Boa ...Seguinte queria ver se pode me ajudar ...

    Tenho que criar um jogo river raid em c..

    MAs estou sem saber como começar ...

    Tem como dar um Luz ...algum código ...Obrigado !!!T+++

  • Anônimo
    avatar

    Vai fazer do zero? Se sim, comece pelo básico, faça o código para inicializar uma janela, mostrar gráficos e vá evoluindo. Aqui no porta temos diversos artigos que cobrem coisas básicas, além de exemplos de jogos.

  • Rodrigo
    avatar

    Bruno, você teria algum material onde se explica a organização de objetos em forma de componentes?
    Obrigado desde já.

Escrever um comentário
Your Contact Details:
Gravatar enabled
Comentário:
[b] [i] [u] [url] [quote] [code] [img]   
:angry::0:confused::cheer:B):evil::silly::dry::lol::kiss::D:pinch::(:shock:
:X:side::):P:unsure::woohoo::huh::whistle:;):S:!::?::idea::arrow:
Security
Por favor coloque o código anti-spam que você lê na imagem.
LAST_UPDATED2  

Busca

Linguagens

Twitter