Algumas convenções

25 11 2007

Enquanto o primeiro artigo sobre a criação de jogos não fica pronto, achei conveniente escrever esse aqui, para que partamos do mesmo ponto. Em primeiro lugar, estou assumindo que todos vocês:

  • Já estudaram C++ em algum momento de suas vidas;
  • Conhecem os conceitos básicos de programação, incluindo orientação à objetos;

Ainda não é o seu perfil? Então, vale a pena relembrar alguns links já passados no artigo sobre que linguagem de programação usar:

http://www.bdjogos.com/conteudo.php?link=capitulo_08.php (em português)
http://www.cplusplus.com/doc/tutorial/
http://www.inf.uni-konstanz.de/~kuehl/c++-faq/

Convenções de código

O C++ é uma linguagem antiga, se comparada ao Java ou ao C#. No decorrer dos anos, várias convenções de código foram criadas e adotadas. Eu, como todos os programadores, aderi a algumas delas (coincidentemente, são muito parecidas com as atuais convenções do Java):

  • Nomes de classes iniciam com letras maiúsculas, e o nome prossegue no estilo “camel case” (ou seja, com a primeira letra de cada outra palavra maiuscula). Se a classe começar com uma sigla, só a primeira letra da sigla se torna maiúscula. Exemplos: CameraMan, BigBoss, Player, SdlImage. Note que não uso prefixos ou underscore (_);
  • Nomes de variáveis iniciam com letras minúsculas, no resto, seguem o mesmo estilo das classes: uglyEnemy, sdlImage, life, playerPosition;
  • Chaves são colocadas na linha de baixo, seja no comando ou em métodos. E não uso chaves em ifs ou whiles com um só comando, a menos que isso torne o código mais claro (em ifs dentro de ifs, por exemplo). Exemplos:
//If só com um comando
if (x == 1)
    doSomething();
else
    doSomethingElse();

//Ifs aninhados
if (x==1)  //Esse if ficaria confuso sem as chaves.
{
    if (a == b)
       x++;
    else //Pois ficaria difícil dizer de quem é esse else
       x--;
}

//While com múltiplos comandos
while (gameIsPlaying)
{
    readInput();
    process();
    render();
}
  • Sou totalmente contra prefixos de qualquer tipo. Em nomes de classes, variáveis, parâmetros ou atributos. Entretanto, uso o prefixo _ para parâmetros de um construtor que tenham o mesmo nome de um atributo e o prefixo p para ponteiros. Os prefixos só são usados para evitar código ambíguo, portanto, uma classe que só trabalhe com ponteiros não precisa prefixa-los com p.
  • Acho que nem seria necessário dizer, mas identação está presente no código inteiro. Como padrão, uso 3 espaços.
  • Todo código que desenvolvo é em inglês (não um inglês perfeito, off course, mas eu tento). Por motivos didáticos, comentários serão deixados em português. Mas não se surpreenda se, ao baixar um de meus projetos prontos, você se deparar com um código integralmente em inglês. Motivo? É mais fácil para pedir a ajuda em fóruns internacionais;
  • Dou preferência ao paradigma orientado à objetos;
  • Dou preferência a um código seguro ao invés de um código rápido: isso inclui manter os atributos privados e acessa-los através de gets e sets, usar exceptions e validar parâmetros;
  • Dou preferência a clareza ao invés de performance. Assim, inteiros ou ponteiros não são implicitamente usados como booleanos, fujo de expressões que necessitem de profundo conhecimento da precedência dos operadores e não poupo na criação de classes ou métodos.
bool isPlaying = true;
int x = 10;
Enemy* anEnemy = NULL;

//Errado! Conversão implícita de um inteiro para booleano
//Segundo a convenção, o correto é while (x > 0) e,
//na primeira linha, x--;
while (x--)
{
   doSomething();
}

//Errado! Conversão implicita de um ponteiro para um booleano
if (!anEnemy)  //Pela convenção seria if (anEnemy == NULL)
{
    playVictory();
}

//Ok! Uso de um booleano.
//Note que não é necessário fazer while(isPlaying == true)
while (isPlaying)
{
     playGame();
}
  • Dou preferência ao uso da biblioteca padrão. O maior impacto disso é que prefiro std::string no lugar de char* e std::vector no lugar de arrays primitivos. Se você não está familiarizado com a biblioteca padrão, não se preocupe. Farei uma pequena revisão dos seus principais elementos no futuro.

That’s all folks!

No próximo artigo, veremos como inicializar a SDL e sobre como criar a janela de seu jogo.