Este blog esta em reforma no momento.

Montando um mini-mapa

Este é o mini-mapa do jogo, depois irei adicionar mais uns sprites para servirem de botões e decoração.

Deu um trabalho bastante razoável fazer esse danadinho. A parte chata ficou em acertar as transformações de coordenadas do personagem no mapa para o mini-mapa. Mas falarei delas abaixo para não torturar os que não programam.

O design do mini-mapa
Ficou a cargo do Blender, achei ele mais interessante para produzir gráficos vetoriais. Depois um pintura por cima pode dar um retoque.
Produzi 3 texturas cada um dos elementos da interface.
Precisei mais uma textura para servir de mascara para recortar o mapa e uma outra para ficar dando scroll e gerar o efeito da animação.

O legal da OGRE é que você pode fazer muita coisa sem programar, apenas setando parâmetros no material. O material e a definição dos elementos foram fáceis de produzir:
minimap.material
material minimap01
{
 technique
 {
  pass miniatura
  {
            lighting off
            scene_blend alpha_blend
            depth_write off
            
            texture_unit mapa
            {
                //texture           minimap_vazio.jpg
                texture             mapa_00_0.jpg 2d 1
                tex_address_mode    border
                tex_border          colour 0.0 0.0 0.0 1.0
           colour_op           modulate
            }
            
            texture_unit
            {
               texture minimap_mask.png
            }
  }
 }
}


material minimap02
{
 technique
 {
  pass
  {
            lighting off
            scene_blend alpha_blend
            depth_write off
            
            texture_unit
            {
                texture minimap_over.png 2d 1
           colour_op modulate
            }
            
  }
 }
}

material minimap03
{
 technique
 {
  pass
  {
            lighting off
            scene_blend alpha_blend
            depth_write off
            
            texture_unit marcas
            {
                texture      minimap_over_mk.png 2d 1
                color_op     modulate
            }
            
            texture_unit radar
            {
                texture      minimap_radar.png 2d 1
                color_op     add
                scroll_anim  0 0.35
            }
            
  }
 }
}

material minimap04
{
 technique
 {
  pass
  {
            lighting off
            scene_blend add
            depth_write off
            
            texture_unit
            {
                texture minimap_over_l.png 2d 1
           colour_op modulate
            }
            
  }
 }
}
minimap.overlay
MiniMap
{
 zorder 200


 container Panel(MiniMap/Map)
    {
        metrics_mode pixels
        width       128
        height      128
        left        -130
        top         2
        vert_align  top
        horz_align  right
        material    minimap01
        uv_coords   0.0 0.0 1.0 1.0
        
    }
    
    container Panel(MiniMap/Ov3)
    {
        metrics_mode pixels
        width       128
        height      128
        left        -130
        top         2
        vert_align  top
        horz_align  right
        material    minimap03
        uv_coords   0.0 0.0 1.0 1.0
        
    }
    
    container Panel(MiniMap/Ov2)
    {
        metrics_mode pixels
        width       128
        height      128
        left        -130
        top         2
        vert_align  top
        horz_align  right
        material    minimap04
        uv_coords   0.0 0.0 1.0 1.0
        
    }
    
    container Panel(MiniMap/Ov1)
    {
        metrics_mode pixels
        width       128
        height      128
        left        -130
        top         2
        vert_align  top
        horz_align  right
        material    minimap02
        uv_coords   0.0 0.0 1.0 1.0
        
    }

}

Certos recursos da OGRE também são muito bem pensados, como o de poder atribuir um nome a os elementos do material, como no caso da textura "mapa" que é o mapa do cenário.
Pelo nome fica fácil pega-la e manipula-la, infelizmente essa é a parte que foi complicada.

Código do Mini-mapa (C++ from Hell)
Resolvi implementar o mini-mapa direto em C++ mandando uma classe de controle para Lua.
Isso tornou um tanto trabalhoso acertar o mini-mapa pois toda hora que eu tentava acertar meus cálculos de projeção tinha que compilar todo o fonte e testar de novo.
Esse cálculo foi bem chato, onde char é o personagem e ter o terreno. Como o centro do terreno esta em 0,0 tenho que adicionar a metade da distância do terreno à posição do personagem e depois dividir pela distância total do terreno para obter um valor da fração do terreno que o personagem esta. Assim posso fazer o scroll direto na textura. (é esse cálculo ai em cima)

No final ficou assim:
int MiniMap::OnUpdate(lua_State* L)
{
 if (player)
 {
  int stack = lua_gettop(L);
  if (stack>0 && lua_isnumber(L,1))
  {
   double delta = (double) lua_tonumber(L,1);

   gkVector3 pos = player->getWorldPosition();
   gkEuler rot = player->getWorldRotation();

   double sc = 8.0f / 2.0f;
   unit->setTextureScale(sc,sc);

   static double RAD = 0.017453293f;
   gkRadian rad( (rot.toVector3().z-180) * RAD );
   //unit->setTextureRotate( rad );

   double x = pos.x + limits2.x;// - limitsViewPort.x;
   double y = -pos.y + limits2.y;// - limitsViewPort.y;

   x /= limits.x;
   y /= limits.y;
   unit->setTextureScroll(x-0.5f,y-0.5f);
   
  }
 } else {  }
 return 0;
}

Independente do trabalho extra ficou mais fácil apartir desta classe controlar atributos mais detalhados e usar todos os recursos da OGRE no mini-mapa.

Idéias que podem dar certo
Pensei numa coisa simples mas pode funcionar bem:
Conforme a tendência da personagem vai se ajustando (pela pontuação das ações e dialogos) pode aparecer um anjo ou um demônio abaixo do mostrador do mini-mapa.
Se a figura for o anjo vai indicar ao jogador lugares perigosos.
Se for o demônio vai indicar lugares perigosos ou não e "talvez" tesouros. Ou seja, essa figura mostra mais coisas mas é menos confiável.

Comentários