Arquivo para Novembro, 2007

Renderização e OO – Código

Como prometi, o código que ilustra a parte de renderização. Python não implementa interfaces explícitas, como em Java, então fiz uma ligeira gambiarra com uma classe abstrata. E sim, eu programo em inglês. Me processem :P

# Object renderer abstract class
class Renderer:
    # Default constructor
    #
    # Raises an exception because this class can't
    # be instantiated. It's used as a base class
    # for other renderer classes
    def __init__(self):
        raise "Can't instantiate this abstract class"

    # Renders an object
    #
    # Renders the object based on its class. It uses
    # an ugly chain of "if else isinstance", because
    # Python can't do method overloading (at least
    # not out of the box). Thanks, guys.
    def render(self, object):
        if isinstance(object, Map):
            self.__renderMap__(object)

# Renderer that uses pygame's routines
class PygameRenderer(Renderer):
    # Default constructor
    #
    # Overrides the base class' constructor
    # to prevent an instantiation exception
    def __init__(self):
        pass

    # Renders a map object
    def __renderMap__(self, map):
        print "Rendering map using PyGame!"

# Renderer that uses OpenGL routines
class OpenGLRenderer(Renderer):
    # Default constructor
    #
    # Overrides the base class' constructor
    # to prevent an instantiation exception
    def __init__(self):
        pass

    # Renders a map object
    def __renderMap__(self, map):
        print "Rendering map using OpenGL!"

Comentários (1)

Casa de ferreiro…

Para quem está curioso sobre o que pretendo usar:

Deixe um comentário

Renderização e OO

Independente da definição dos mapas, uma coisa importante é definir a forma com a qual eles serão renderizados, assim como para todos os outros objetos de jogo (jogador, inimigos, etc). Uma abordagem ingênua seria acrescentar um método “renderiza” para cada classe, assim cada classe teria conhecimento de como suas representações devem ser mostradas.

Seria algo como:

class Mapa    /* uma porção de métodos relacionados ao mapa */

    renderizaMapa( ... ) 

A idéia parece legal, mas começa a vazar quando se considera a possibilidade de múltiplos renderizadores. Digamos que além de um renderizador padrão feito com as rotinas do pygame, eu quisesse adicionar um novo renderizador baseado em OpenGL. Fácil! É só adicionar um novo método, “renderizaOpenGL”!

class Mapa

    /* uma porção de métodos relacionados ao mapa */


    renderizaMapaPython( ... )


    renderizaMapaGL( ... )

Mas e se eu quiser adicionar uma outra forma de renderização, por DirectX? Adicionaria um novo método para cada tipo de objeto? Obviamente esta abordagem não é a ideal.Uma solução, que é a que vou seguir, será criar um renderizador de cada tipo, que recebe os objetos que serão renderizados. Assim, para mudar o renderizador para um que usa OpenGL, DirectX ou sinais de fumaça, basta implementar o novo renderizador e substituí-lo, sem modificar o código dos objetos de jogo.

Exemplo para o mapa:

class Mapa

    /* métodos do mapa */ 

interface Renderizador 

    renderizaMapa( Mapa mapa, ... )

class RenderizadorPython implements Renderizador

class RenderizadorOpenGL implements Renderizador

class RenderizadorDirectX implements Renderizador 

Em breve mostro o código Python que ilustra essa idéia. Primeiro preciso estudar como (se) Python trata tipos abstratos de dados :)

Deixe um comentário

Mapa de jogo, inimigos

Mapas

Os mapas do jogo serão baseados em tiles, com camadas. Assim posso definir camadas de “fundo”, “frente”, “máscara”, etc. Dessa forma, um dos metadados de um mapa é uma matriz [l][a][c], onde:

  • l é a largura do mapa, em tiles;
  • a é a altura do mapa, também em tiles;
  • c é o número de camadas do mapa.

Assim, a posição [12][10][1] daria o objeto na camada 1 e posição (12 * t,10 * t), sendo t o tamanho do tile.

Ainda devem ser definidos como devem ser detectadas as colisões do jogador com o mapa, como lidar com gatilhos de eventos de script e como posicionar os inimigos, o que nos leva a…

Inimigos

Uma coisa que deve ser levada em consideração é o posicionamento dos inimigos, mas isso depende de uma decisão de design: Os inimigos “reaparecem” quando o jogador passa por uma certa posição (pense Megaman), ou só reaparecem ao sair/entrar de um mapa (Castlevania SOTN e outros recentes)?

A primeira opção seria mais interessante com a implementação de um sistema de níveis, no qual o jogador pode acumular experiência ao eliminar inimigos. O problema é que esse sistema, se não balanceado corretamente, pode forçar o jogador a parar o progresso para alcançar um certo nível, o que considero uma forma artificial de aumentar o tempo de jogo, sem contar que é chato pacas. Sendo assim, creio que seja adequada a segunda opção.

Deixe um comentário

World 1-1 Paolo Start!

Olá.

Eu não gosto de enrolação, então vamos aos fatos:

  • Quem é você?
    • Paolo Victor, 22.
  • Pra quê esse blog?
    • Este blog será usado como blog de desenvolvimento de um jogo, que pretendo desenvolver usando Python.
  • Que jogo?
    • Definidos estão apenas o tipo (híbrido metroid/castlevania) e parte da estória.
  • Por que Python?
    • Quero aprender Python;
    • As bibliotecas de Python podem ajudar/agilizar as coisas;
    • Python é cool.
  • Quando fica pronto?
    • Boa pergunta :)
  • E o que que eu tenho a ver com isso?
    • Estou criando este blog para compartilhar minha jornada (poético?) com quem estiver interessado. Pretendo postar não apenas informações sobre o progresso, mas também falar sobre o funcionamento interno, dificuldades, erros cometidos, etc. Assim, esta pode ser uma ferramenta de aprendizado tanto para mim, quanto para outros que pretendem ou já estão desenvolvendo algum jogo em Python.

E é isso. Nas próximas horas pretendo começar a por a mão na massa, começando pelo planejamento da engine de plataforma. Sigam-me os bons!

Deixe um comentário