segunda-feira, 7 de janeiro de 2013

Conclusão

Chegamos ao final deste blog. Para acessar de uma forma fácil todas as postagens utilize o SUMÁRIO.

Se você estiver interessado em conhecer mais sobre a área de desenvolvimento de jogos dê uma olhada em diversos materiais didáticos que eu já produzi nesta área. Vou comentar sobre alguns deles.

  • Game Design Compendium
A série Game Design Compendium contém 20 apresentações voltada para iniciantes na área de desenvolvimento de jogos e aborda diversos conceitos fundamentais de Game Design.

As apresentações estão disponíveis neste link: Game Design Compendium.



  • MRDX
O MRDX é uma biblioteca para programação de jogos em C/C++ que eu implementei em 2001 com o objetivo de facilitar o ensino nesta área. O MRDX foi apresentado no 1º Workshop Brasileiro de Desenvolvimento de Jogos (WJogos) que ocorreu em Fortaleza no ano de 2002.

Os textos que acompanham o MRDX são bem didáticos e apresentam noções básicas de programação de jogos que são úteis independente da linguagem de programação que você estiver utilizando atualmente.

O MRDX pode ser baixado neste link: MRDX.



  • UnrealScript
UnrealScript é uma linguagem de programação orientada a objetos utilizada para programar jogos 3D na Unreal Engine. Em novembro/2009, a empresa Epic Games lançou o Unreal Development Kit (UDK) que pode ser usado livremente para fins não comerciais.

Criei uma série de 40 artigos em português ensinando a programação de jogos no UDK com UnrealScript. Os artigos podem ser acessados neste link: Sumário UnrealScript.


sexta-feira, 4 de janeiro de 2013

Uso de Arquivo para os Recordes


Os recordes das fases do Mina 2 são gravados em um arquivo quando o programa é finalizado para que estes recordes possam ser recuperados na próxima execução do Mina 2. Se este arquivo não fosse usado, os valores dos Recordes sempre retornariam ao valor padrão em uma nova execução do jogo.

A variável com o nome "frec" é usada para referenciar o arquivo que guarda os recordes no Mina 2. Ela foi definida da seguinte forma:
type tiporecorde = record
                      nome:string[10];
                      score:integer;
                   end;

var frec: file of tiporecorde;

Como pode ser visto no Laço Principal, no começo da execução do programa, a variável "frec" é associada ao nome de arquivo "recordes.mi2" através da procedure assign():
assign(frec,'recordes.mi2');

Logo após é chamada a procedure verificarecordes que irá procurar pelo arquivo "recordes.mi2" e carregar os valores de recordes caso o arquivo seja encontrado. Se o aquivo não existir, serão utilizados os valores padrões para os recordes.

O código da procedure verificarecordes é o seguinte:
procedure verificarecordes;            
var texto1:PathStr;
    ind:integer;
begin
     texto1:=FSearch('recordes.mi2','.');
     if texto1 = '' then
        for ind:=1 to QF do
          begin
            recordes[ind].nome:='Computador';
            recordes[ind].score:=100;
          end
     else
        begin
          reset(frec);
          for ind:=1 to QF do
              read(frec,recordes[ind]);
        end;
end;

A procedure gravarecordes é chamada quando for escolhida a opção "Finalizar" na procedure menu. Esta procedure é responsável por gravar os recordes atuais das fases no arquivo "recordes.mi2".

Código da procedure gravarecordes:
procedure gravarecordes;            
var ind:integer;
begin
  rewrite(frec);
  for ind:=1 to QF do
      write(frec,recordes[ind]);
  close(frec);
end;

A tela de recordes é acessada a partir do Menu Principal do Mina 2. A procedure procrecorde controla esta tela que é apenas informativa. É feito um conjunto de movimentações com os textos para montar a tela. O trecho de código abaixo é responsável por mover os textos que contém o recorde de cada fase da direita para esquerda até sua posição correta.
 {trecho da procedure procrecorde}

  for rec:= 1 to QF do
      begin
           str(recordes[rec].score:3,s);
           str(rec:2,strfase);
           s:= 'FASE '+ strfase+' : '+ s + ' - '+ recordes[rec].nome;
           for ind:=80 downto 25 do
               begin
                    x:=81-ind;
                    if x>26 then x:=26;
                    gotoxy(ind,(rec*2)+6);
                    write(copy(s,1,x));
                    escondecursor;
                    textcolor(14);
                    delay(20);
                    if ind <> 25 then
                       apagalinha((rec*2)+6);
               end;
      end;

quinta-feira, 3 de janeiro de 2013

Procedure fimdejogo


A procedure fimdejogo é chamada a partir da procedure jogo quando o Tempo da fase chega a zero. Esta procedure mostra o Placar da partida com os pontos dos jogadores e indica se o recorde atual da fase foi superado.

O código da procedure fimdejogo foi dividido em três partes nesta postagem para facilitar a explicação.

A 1ª parte realiza uma pequena animação que mostra os textos "PLACAR" e "MINA 2" descendo lentamente a partir do topo da tela.
procedure fimdejogo;
var ind,col,tecla_res:integer;
    s,strfase:string;
begin
  apagatela;
  textcolor(15);

  for ind:=1 to 5 do
      begin
           gotoxy(36,ind);
           write('PLACAR');
           escondecursor;
           textcolor(15);
           delay(100);
           if ind <> 5 then
                  apagalinha(ind);
      end;

  for ind:=1 to 3 do
      begin
           gotoxy(36,ind);
           write('MINA 2');
           escondecursor;
           textcolor(15);
           delay(100);
           if ind <> 3 then
                  apagalinha(ind);
      end;

A 2ª parte escreve os nomes e os pontos dos jogadores na tela. Caso esteja no modo de 2 jogadores é verificado a pontuação de cada jogador para determinar o vencedor ou se a partida acabou em Empate.
  for ind:=1 to qjog do   
   begin
    textcolor(jog[ind].cor);
    if ind=1 then
       col:=47
    else
       col:=23;
    gotoxy(col,8);
    write(extrainfo[ind].nome);
    gotoxy(col+2,10);
    write(extrainfo[ind].score:3);
   end;
   textcolor(15);
   ind:=1;
   if qjog=2 then
    if extrainfo[1].score = extrainfo[2].score then
     begin
       gotoxy(36,12);
       write('EMPATE');
     end
    else
     begin
       if extrainfo[1].score > extrainfo[2].score then
          ind:=1
       else
          ind:=2;
       gotoxy(30,12);
       write('VENCEDOR : '+ extrainfo[ind].nome);
     end;

A 3ª parte verifica se os pontos do vencedor foram maior do que o recorde atual da fase. Se isto acontecer será exibido na tela o texto "NOVO RECORDE!" junto com as informações relacionadas ao recorde. O nome e os pontos do jogador serão armazenados no vetor "recordes[]" que guarda os recordes de todas as fases. No final do código a procedure enfeite é chamada para fazer a animação da borda até que a tecla ENTER seja pressionada.
   if extrainfo[ind].score > recordes[fase].score then
    begin
     textcolor(15+blink);
     gotoxy(32,14);
     write('NOVO RECORDE!');
     textcolor(15);
     recordes[fase].score := extrainfo[ind].score;
     recordes[fase].nome := extrainfo[ind].nome;
     str(recordes[fase].score:3,s);
     str(fase:2,strfase);
     s:= 'FASE '+ strfase+' : '+ s + ' - '+ recordes[fase].nome;
     gotoxy(28,16);
     write(s);
    end;
  gotoxy(25,20);
  write('Pressione ENTER para continuar.');
  repeat
   enfeite;
   tecla_res:=ord(upcase(readkey));
   if tecla_res=0 then tecla_res:=ord(readkey)+255;
  until tecla_res=ENT;
end;

quarta-feira, 2 de janeiro de 2013

Procedures utilitárias

Existem diversas procedures utilitárias no Mina 2 que serão analisadas nesta postagem.

A procedure informa escreve no topo da tela o tempo restante e qual jogador está vencendo. Nas laterais são escritos os nomes e pontos dos jogadores de acordo com a cor de cada jogador como pode ser visto nesta imagem.


Os nomes e os pontos dos jogadores estão armazenados no vetor "extrainfo[]". Este é o código da procedure informa:
procedure informa;
var ind,col:integer;
begin
 for ind:=1 to qjog do   {nome e ponto do jog}
  begin
    apagalinha(5);
    textcolor(jog[ind].cor);
    if ind=1 then
       col:=67
    else
       col:=3;
    gotoxy(col,10);
    write(extrainfo[ind].nome);
    gotoxy(col+2,12);
    write(extrainfo[ind].score:3);
  end;
  textcolor(15);
  if qjog=2 then
    if extrainfo[1].score = extrainfo[2].score then
       msg('     Empate')
    else
     begin
       if extrainfo[1].score > extrainfo[2].score then
          ind:=1
       else
          ind:=2;
       msg(extrainfo[ind].nome + ' esta vencendo.');
     end;
  gotoxy(35,3);
  textcolor(15);
  if tempo<=10 then textcolor(15+blink);
  write('TEMPO: ',tempo:2);
end;

Existe outra procedure chamada mostra que é responsável por exibir na tela os caracteres que representam os jogadores e seus objetos, além das bolas que ameaçam os jogadores. Esta procedure e a procedure informa são chamadas a partir da procedure jogo.

As informações necessárias para a exibição de todos os itens estão nos vetores "jog[]", "obj[]" e "bola[]". Estes vetores são do tipo "geral" como pode ser visto na postagem Definição das variáveis.
procedure mostra;
var ind:integer;
begin
  for ind:=1 to qjog do
    begin
      textcolor(jog[ind].cor);

      gotoxy(obj[ind].col + difcol, obj[ind].lin + diflin);
      write(chr(obj[ind].cara));

      gotoxy(jog[ind].col + difcol, jog[ind].lin + diflin);
      write(chr(jog[ind].cara));
    end;

  if qbola > 0 then
   for ind:= 1 to qbola do
    begin
      textcolor(15); {branco}
      gotoxy(bola[ind].col + difcol, bola[ind].lin + diflin);
      write('0');
    end;
end;

A procedure inicia procura uma posição aleatória na fase que não contenha um bloco. Esta procedure utiliza passagem de parâmetros por referência. Isto é feito usando a palavra "var" na frente dos nomes dos parâmetros. Na passagem por referência, as variáveis originais que foram passadas para a procedure tem os seus valores modificados.
procedure inicia(var nlin, ncol:integer);
begin
   repeat
     nlin := random( altura ) + 1;
     ncol := random( largura) + 1;
   until mapa[ nlin, ncol ] = 0;
end;

A procedure morte é chamada quando ocorre algum tipo de colisão do jogador. Ela desenha um "*" na posição atual do jogador e exibe uma mensagem no topo da tela com o nome do jogador que explodiu. Depois faz uma pequena pausa e subtrai 5 pontos do jogador.
procedure morte(x:integer);
begin
  apagalinha(5);
  sound(50);
  textcolor(jog[x].cor);
  gotoxy(jog[x].col + difcol, jog[x].lin + diflin);
  write('*');
  msg(extrainfo[x].nome + ' explodiu.');
  delay(300);
  nosound;
  delay(400);
  apagalinha(5);
  extrainfo[x].score := extrainfo[x].score - 5;
  jog[x].direcao := 0;
end;