Hexfeld: Unterschied zwischen den Versionen

Aus DGL Wiki
Wechseln zu: Navigation, Suche
K (Ein paar Ausbesserungen)
K (Der Ausdruck ''<pascal>(.*?)</pascal>'' wurde ersetzt mit ''<source lang="pascal">$1</source>''.)
 
Zeile 22: Zeile 22:
 
Einfache Beispielimplementation :
 
Einfache Beispielimplementation :
  
<pascal>type
+
<source lang="pascal">type
 
   THex = record
 
   THex = record
 
     TextureID : glUInt;
 
     TextureID : glUInt;
Zeile 29: Zeile 29:
  
 
  var  
 
  var  
   Hexfeld : array[-16..16, -16..16] of THex;</pascal>
+
   Hexfeld : array[-16..16, -16..16] of THex;</source>
  
  
Zeile 41: Zeile 41:
  
  
<pascal>
+
<source lang="pascal">
 
for x := Low(Hexfeld) to High(Hexfeld) do
 
for x := Low(Hexfeld) to High(Hexfeld) do
 
  for y := Low(Hexfeld) to High(Hexfeld) do
 
  for y := Low(Hexfeld) to High(Hexfeld) do
Zeile 58: Zeile 58:
 
   glPopMatrix;
 
   glPopMatrix;
 
   end;
 
   end;
</pascal>
+
</source>

Aktuelle Version vom 10. März 2009, 19:05 Uhr

Hexfelder

Beschreibung

Ein Hexfeld ist eine beliebte Methode um Spielfelder vor allem in Strategiespielen darzustellen. Das Hex deutet dabei bereits auf die Form der Felder hin (griechisch Hexa = 6, also Sechseck), die Reihe für Reihe versetzt gerendert werden.


Hexfeld 3d.jpg Hexfeld bird.jpg

Das linke Bild zeigt ein Hexfeld inklusive selektierter Einheit und deren Bewegungsradius in 3D, das rechte Bild zeigt die Draufsicht und lässt vor allem das versetzte Zeichnen der einzelnen Hexreihen gut erkennen.


Verwaltung

Verwaltet werden die Hexfelder genauso wie ihre viereckigen "Kameraden", nämlich in einem 2D-Array. Genauso verhält es sich mit dem Bewegungsradius von Einheiten, hier muss man ganz einfach die sechs angrenzenden Felder ermitteln. Um den Versatz der Felder muss man sich dabei nicht kümmern, da dies nur rein optischer Natur ist. Rein programmiertechnisch liegen die Felder immer noch benachbart jeweils in X- und Y-Richtung im 2D-Array :

Hexfeld rand.jpg Hexfeld rand coords.jpg

Auf dem linken Bild kann man gut erkennen, wie die Hexfelder am Rand einfach nur versetzt gerendert werden, um ineinander zu passen. Wenn man z.B. die mittlere Reihe um 50% Feldbreite nach links ziehen würde, hätte man die Feldlage entsprechend des 2D-Arrays. Um dies zu verdeutlichen, zeigt das rechte Bild die Arraykoordinaten der umgebenden Felder.


Einfache Beispielimplementation :

type
  THex = record
    TextureID : glUInt;
    ...
   end;

 var 
  Hexfeld : array[-16..16, -16..16] of THex;


Rendern

Am bequemsten lassen sich Hexfelder über den Primitivenmodus GL_Polygon rendern. Dieser ist zwar weniger performant als die direkte Übergabe von Dreiecken, allerdings sind Hexfelder in der Regel statisch und können daher direkt in einer Displayliste abgelegt werden, die von der jeweiligen OpenGL-Implementation optimiert wird. Animierte Objekte und Einheiten selbst sind ja kein Teil des Hexfeldes selbst und können dann separat gerendert werden.

Implementation

Dies ist die simpelste Form, ein komplettes Hexfeld zu rendern. Dabei wird jedes Feld entsprechend seiner Arrayposition versetzt und dann als Polygon gezeichnet. Im Normalfall packt man diese Prozedur in eine Displayliste, die dann später nur noch aufgerufen wird. Zusätzlich kann man hier über ein zweites Polygon sowie sechs Rechtecke noch einen Boden inklusive Seiten einbauen. Texturen fließen bei dieser Methode nicht ineinander über, es sei denn, dies wurde bereits in der Textur implementiert. Will man also weiche Übergänge, muss man hier via Blending und Multitexturing oder mit Shadern zwischen den benachbarten Texturen blenden.


for x := Low(Hexfeld) to High(Hexfeld) do
 for y := Low(Hexfeld) to High(Hexfeld) do
  begin
  glBindTexture(HexFeld[x,y].TextureID, GL_TEXTURE_2D);
  glPushMatrix;
   glTranslatef(x*2*1.75 + (y and 1)*1.75, 0, y*3);
   glBegin(GL_POLYGON);
    glTexCoord2f(0,   -0.25);  glVertex3f(0,    0, -1);
    glTexCoord2f(0.5, -0);     glVertex3f(1.75, 0,  0);
    glTexCoord2f(1,   -0.25);  glVertex3f(3.5,  0, -1);
    glTexCoord2f(1,   -0.75);  glVertex3f(3.5,  0, -3);
    glTexCoord2f(0.5, -1);     glVertex3f(1.75, 0, -4);
    glTexCoord2f(0,   -0.75);  glVertex3f(0,    0, -3);
   glEnd;
  glPopMatrix;
  end;