Войти
ПрограммированиеФорумГрафика

Как создать миникарту? (2 стр)

Страницы: 1 2
#15
8:05, 9 апр. 2021

Есть пример миникарты для ку2, с показом врагов и айтемов. Не знаю, поможет или нет.


#16
10:48, 9 апр. 2021

tonline_kms65
Понял. Карта должна перемещаться вместе с танком? Опять же, не знаю возможностей движка, но в таком случае нужно идти не от карты, а от танка.
Если есть координаты танка, делаем матрицу, которая переводит из ворлд спейс к танк спейс(его координата равна нулю).
Потом отбрасывает все, что выходит за единичный квадрат [-1, 1]
И далее все то, что после UPD идет.

Матрица M1 в таком случае равна

1/mMaxX 0 0 -tPX
0 1/mMaxY 0 -tPY
0 0 0 0
0 0 0 1

Где mMaxX, mMaxY - размер миникарты в ворлдспейс, tPX, tPY - координаты танка в ворлдспейс.

Вектор объекта V1 на миникарте (x, y, z, 1),  где xyz - координаты объекта в ворлд спейс.

Потом M1*V1 и получаются координаты в танк спейс. Если выходит за единичный квадрат - отсекается.

Можно еще на матрицу поворота по желанию умножить.

P.s. писал в маршрутке, могут быть опечатки.

#17
(Правка: 4:32) 4:21, 23 апр. 2021

barnes
> Есть пример миникарты для ку2, с показом врагов и айтемов. Не знаю, поможет или
> нет.

Не помешал бы пример, не знаю что это за игра, но  в принципе всё-равно какая игра.

Kaylent
> Карта должна перемещаться вместе с танком? Опять же, не знаю возможностей
> движка, но в таком случае нужно идти не от карты, а от танка.

Спасибо за ответ. Это очень интересно.
Я не знаю как лучше, что вокруг чего должно вращаться:
  1. танк(маркер) показывать на статичной мини-карте
  2. карта вращается и двигается вокруг маркера(спрайта) танка, а сам спрайт танка стоит статично.

Как по мне, второй вариант меня устроил бы намного больше, но пойдет и первый вариант(для начала, потом уже можно дальше идти)

На данный момент я сообразил, как, технически, можно отображать нужные мне маркеры(спрайты) на мини-карте. Это было основной технической задачей, уже стали появляться сомнения что этот вопрос можно решить без дополнительного расширения, но слава Богу оказалось решаемо без расширений.

Остаётся чисто математический вопрос - проекция 3D координат нужных мне объектов в 2D плоскость(мини-карту), с координатами соответствующими размерам мини-карты.
У меня есть координаты верхнего левого угла мини-карты, есть её размер(scale), естественно есть мировые координаты и углы танка. В принципе есть всё, остаётся понять как это можно использовать. Кстати, мини-карта сделана текстурой(1024*1024).

Не совсем понимаю твой пример, вернее сказать, вообще не понимаю, как нибудь бы в коде. Любой язык. Желательно без библиотек этого языка(если можно)

#18
(Правка: 23:28) 5:12, 23 апр. 2021

Вот скрин с мини-картой на сегодня. На ней видно сам маркер танка с направлением его "взгляда".
Мини-карта сейчас крутится вокруг своего центра, спрайт танка вокруг своего, естественно ни о какой правильности работы даже речи нет. Как в басне. 
Мне нужно этот раздрай заставить работать правильно. Думаю центом мини-карты(текстуры) должен быть не её центр, а координаты, где находится танк, и все вращение мини-карты уже должно производиться относительно этого центра, а не её собственного.
minimap_1 | Как создать миникарту?

#19
10:40, 23 апр. 2021

tonline_kms65
> Не помешал бы пример, не знаю что это за игра, но  в принципе всё-равно какая
> игра.

//sul's minimap thing
void R_RecursiveRadarNode (mnode_t *node)
{
  int      c, side, sidebit;
  cplane_t  *plane;
  msurface_t  *surf, **mark;
  mleaf_t    *pleaf;
  float    dot,distance;
  glpoly_t  *p;
  float    *v;
  int      i;

  if (node->contents == CONTENTS_SOLID)  return;    // solid

  if(gl_minimap_zoom->value>=0.1) {
    distance = 1024.0/gl_minimap_zoom->value;
  } else {
    distance = 1024.0;
  }

  if ( r_origin[0]+distance < node->minmaxs[0] ||
     r_origin[0]-distance > node->minmaxs[3] ||
     r_origin[1]+distance < node->minmaxs[1] ||
     r_origin[1]-distance > node->minmaxs[4] ||
     r_origin[2]+256 < node->minmaxs[2] ||
     r_origin[2]-256 > node->minmaxs[5]) return;
  
  // if a leaf node, draw stuff
  if (node->contents != -1) {
    pleaf = (mleaf_t *)node;
    // check for door connected areas
    if (r_newrefdef.areabits) {
      // not visible
      if (! (r_newrefdef.areabits[pleaf->area>>3] & (1<<(pleaf->area&7)) ) ) return;
    }
    mark = pleaf->firstmarksurface;
    c = pleaf->nummarksurfaces;

    if (c) {
      do {
        (*mark)->visframe = r_framecount;
        mark++;
      } while (--c);
    }
    return;
  }

// node is just a decision point, so go down the apropriate sides
// find which side of the node we are on
  plane = node->plane;  

  switch (plane->type) {
  case PLANE_X:
    dot = modelorg[0] - plane->dist;
    break;
  case PLANE_Y:
    dot = modelorg[1] - plane->dist;
    break;
  case PLANE_Z:
    dot = modelorg[2] - plane->dist;
    break;
  default:
    dot = DotProduct (modelorg, plane->normal) - plane->dist;
    break;
  }

  if (dot >= 0) {
    side = 0;
    sidebit = 0;
  } else {
    side = 1;
    sidebit = SURF_PLANEBACK;
  }

// recurse down the children, front side first
  R_RecursiveRadarNode (node->children[side]);

  if(plane->normal[2]) {      
    // draw stuff    
    if(plane->normal[2]>0) for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++)
    {
      if (surf->texinfo->flags & SURF_SKY){
        continue;
      }
          
      if (surf->texinfo->flags & (SURF_TRANS33|SURF_TRANS66)) {
        qglColor4f(0,1,0,0.5);
      } else if (surf->texinfo->flags & (SURF_WARP|SURF_FLOWING)) {
        qglColor4f(0,0,1,0.5); 
      } else {
        qglColor4f(1,1,1,1);    
      }

      for ( p = surf->polys; p; p = p->chain ) {
        v = p->verts[0];
        qglBegin (GL_TRIANGLE_FAN);
        for (i=0 ; i< p->numverts; i++, v+= VERTEXSIZE) {
          qglVertex3fv (v);
        }
        qglEnd ();
      }   
      
    }
  } else {
    qglDisable(GL_TEXTURE_2D);
    for ( c = node->numsurfaces, surf = r_worldmodel->surfaces + node->firstsurface; c ; c--, surf++) {
      float sColor,C[4];
      if (surf->texinfo->flags & SURF_SKY) continue;
    
      if (surf->texinfo->flags & (SURF_WARP|SURF_FLOWING|SURF_TRANS33|SURF_TRANS66)) {
        sColor=0.5;
      } else {
        sColor=0;
      }
          
      for ( p = surf->polys; p; p = p->chain ) {
        v = p->verts[0];      
            qglBegin (GL_LINE_STRIP);
        for (i=0 ; i< p->numverts; i++, v+= VERTEXSIZE) {
          C[3]= (v[2]-r_origin[2])/256.0;        
          if (C[3]>0) {     
            C[0]=0.5;
            C[1]=0.5+sColor;
            C[2]=0.5;
            C[3]=1-C[3];
          } else {  
            C[0]=0.5;
            C[1]=sColor;
            C[2]=0;
            C[3]+=1;
          }

          if(C[3]<0) {
            C[3]=0;    
          }
          qglColor4fv(C);
          qglVertex3fv (v);
        }
        qglEnd ();
      }           
    }
    qglEnable(GL_TEXTURE_2D);
  }
  // recurse down the back side
  R_RecursiveRadarNode (node->children[!side]);
}

int      numRadarEnts=0;
RadarEnt_t  RadarEnts[MAX_RADAR_ENTS];

void GL_DrawRadar(void)
{  
  int    i;
  float  fS[4]={0,0,-1.0/512.0,0};  

  qglViewport (vid.width-gl_minimap_size->value,0, gl_minimap_size->value, gl_minimap_size->value);  
    
  GL_TexEnv( GL_MODULATE );
  qglMatrixMode(GL_PROJECTION);
  qglPushMatrix();
  qglLoadIdentity ();      

  if (gl_minimap_style->value) {
    qglOrtho(-1024,1024,-1024,1024,-256,256);
  } else {
    qglOrtho(-1024,1024,-512,1536,-256,256);
  }
  qglMatrixMode(GL_MODELVIEW);  
  qglPushMatrix();  
  qglLoadIdentity ();
    
  qglDisable(GL_DEPTH_TEST);
  if (have_stencil) {
    qglClearStencil(0);
    qglClear(GL_STENCIL_BUFFER_BIT);
    qglEnable(GL_STENCIL_TEST);
    qglStencilFunc(GL_ALWAYS,4,4);
    qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
    
    GLSTATE_ENABLE_ALPHATEST;
    qglAlphaFunc(GL_LESS,0.1);
    qglColorMask(0,0,0,0);
      
    qglColor4f(1,1,1,1);
    GL_Bind(r_around->texnum);
    qglBegin(GL_TRIANGLE_FAN);
    if (gl_minimap_style->value){
      qglTexCoord2f(0,1); qglVertex3f(1024,-1024,1);
      qglTexCoord2f(1,1); qglVertex3f(-1024,-1024,1);
      qglTexCoord2f(1,0); qglVertex3f(-1024,1024,1);
      qglTexCoord2f(0,0); qglVertex3f(1024,1024,1);
    } else {
      qglTexCoord2f(0,1); qglVertex3f(1024,-512,1);
      qglTexCoord2f(1,1); qglVertex3f(-1024,-512,1);
      qglTexCoord2f(1,0); qglVertex3f(-1024,1536,1);
      qglTexCoord2f(0,0); qglVertex3f(1024,1536,1);
    }
    qglEnd();    

    qglColorMask(1,1,1,1);
    GLSTATE_DISABLE_ALPHATEST;
    qglAlphaFunc(GL_GREATER, 0.666);
    qglStencilOp(GL_KEEP,GL_KEEP,GL_REPLACE);
    qglStencilFunc(GL_NOTEQUAL,4,4);
  }
       
  if(gl_minimap_zoom->value>=0.1) {
    qglScalef(gl_minimap_zoom->value,gl_minimap_zoom->value,gl_minimap_zoom->value); 
  }

  if (gl_minimap_style->value) {
    qglPushMatrix();  
    qglRotatef (90-r_newrefdef.viewangles[1],  0, 0, -1);        
    
    qglDisable(GL_TEXTURE_2D);
    qglBegin(GL_TRIANGLES);  
    qglColor4f(1,1,1,0.5);
    qglVertex3f(0,32,0);
    qglColor4f(1,0,0,0.5);
    qglVertex3f(24,-32,0);
    qglVertex3f(-24,-32,0);
    qglEnd();
    
    qglPopMatrix();  
  } else {
    qglDisable(GL_TEXTURE_2D);
    qglBegin(GL_TRIANGLES);  
    qglColor4f(1,1,1,0.5);
    qglVertex3f(0,32,0);
    qglColor4f(1,0,0,0.5);
    qglVertex3f(24,-32,0);
    qglVertex3f(-24,-32,0);
    qglEnd();

    qglRotatef (90-r_newrefdef.viewangles[1],  0, 0, 1);        
  }
  qglTranslatef (-r_newrefdef.vieworg[0],  -r_newrefdef.vieworg[1],  -r_newrefdef.vieworg[2]);  

  qglBegin(GL_TRIANGLES);
  for(i=0;i<numRadarEnts;i++){
    float x=RadarEnts[i].org[0];
    float y=RadarEnts[i].org[1];
    float z=RadarEnts[i].org[2];
    qglColor4fv(RadarEnts[i].color);    
    qglVertex3f(x,y+32,z);    
    qglVertex3f(x+27.7128,y-16,z);
    qglVertex3f(x-27.7128,y-16,z);    

    qglVertex3f(x,y-32,z);    
    qglVertex3f(x-27.7128,y+16,z);
    qglVertex3f(x+27.7128,y+16,z);    
  }  
  qglEnd();

  qglEnable(GL_TEXTURE_2D);
    
  GL_Bind(r_radarmap->texnum);
  qglBlendFunc(GL_SRC_ALPHA,GL_ONE);
  GLSTATE_ENABLE_BLEND;
  qglColor3f(1,1,1);
    
  fS[3]=0.5+ r_newrefdef.vieworg[2]/512.0;
  qglTexGenf(GL_S,GL_TEXTURE_GEN_MODE,GL_OBJECT_LINEAR);
    
  GLSTATE_ENABLE_TEXGEN;
  qglTexGenfv(GL_S,GL_OBJECT_PLANE,fS);

  // draw the stuff
  R_RecursiveRadarNode (r_worldmodel->nodes);  

  qglBlendFunc(GL_SRC_ALPHA,GL_ONE_MINUS_SRC_ALPHA);
  GLSTATE_DISABLE_TEXGEN;

  qglPopMatrix();

  if (have_stencil) qglDisable(GL_STENCIL_TEST);

  qglViewport(0,0,vid.width,vid.height);

  GL_TexEnv( GL_REPLACE );
    
  qglMatrixMode(GL_PROJECTION);
  qglPopMatrix();
  qglMatrixMode(GL_MODELVIEW);  
}
#20
10:57, 23 апр. 2021

barnes
> qglPushMatrix()

фуууу

#21
(Правка: 23:33) 23:13, 23 апр. 2021

Ну вот и вся проблема - библиотеки с матрицами, нет в этом языке матриц вращения, либо самому писать, либо что-то другое мутить.
Но за код спасибо - пригодится.
Это с++? Есть сам исходник где посмотреть?

#22
6:03, 24 апр. 2021

barnes

спасибо за код Q
+ Показать
#23
(Правка: 15:18) 15:16, 24 апр. 2021

tonline_kms65
> Ну вот и вся проблема - библиотеки с матрицами, нет в этом языке матриц
> вращения, либо самому писать, либо что-то другое мутить.
> Но за код спасибо - пригодится.
> Это с++? Есть сам исходник где посмотреть?
Это самый обычный ГЛьный матричный стек. q  в начале это наследие Кармака.
Вживую этот код можно увидеть в alien arena. Это мультиплеерная стрелялка на движке второй кваки.

#24
(Правка: 23:26) 23:24, 24 апр. 2021

barnes
> alien arena

Даже не знал что такая игра есть, очередная разновидность кваки.
Но радара и мини-карты я не увидел там, сколько видео пересмотрел.

Код замороченный, должно же быть как-то попроще.

#25
23:53, 24 апр. 2021

tonline_kms65
> Но радара и мини-карты я не увидел там
в консоли r_minimap

#26
(Правка: 23:15) 23:09, 4 мая 2021

Всё! Решил задачу. Мини-карта с радаром в нижнем правом углу, на сегодня отображаются все игроки(убитые крестиками), Дроны и бомба.
Мини-карту пока оставил статичной, когда полностью разберусь в работе кода и исправлю все ошибки - сделаю вращающуюся.

Запустить видео по клику - Как делать игрыЗапустить видео по клику - Как делать игры

Страницы: 1 2
ПрограммированиеФорумГрафика