plotting hex tiles

Started by
2 comments, last by fortress 22 years, 1 month ago
ok everybody heres an easy one or should be anyway need a little help plotting out a screen or map full of 64x64 hex tiles
Advertisement
I am thinking of making a hex-based game myself. You can look at the code I came up with and modify it to suit your purposes if you like. I'm quite a C++ newbie so beware. Anyways here is my "Hexagon" class. Please tell me what you think. Being a newbie, any constructive criticism would be helpful.

    #include <cmath>  // Required for math functions to workHDC g_pHDC; // Global pointer to the device context handleHWND hWnd;  // Global window handle// Point class and definition definition// This is used by the Hex classclass Point {public:  void SetX(int X) {itsX = X;}  void SetY(int Y) {itsY = Y;}  int GetX() const {return itsX;}  int GetY() const {return itsY;}private:  int  itsX;  int  itsY;};// Hexagon class definitionclass Hexagon {  public:    Hexagon();    Hexagon(Point center,int radius);    void SetRadius(int radius);    int GetRadius();    int GetAltitude();    void SetCenterPoint(Point center);    bool IsInsideHex(int X, int Y);    void drawHex(bool drawInfo);  private:    ~Hexagon();      int itsAltitude;    int itsRadius;    Point itsPoints[6];    Point itsCenter;    void calcPoints(void);};// Hexagon ClassHexagon::Hexagon() {}Hexagon::Hexagon(Point center,int radius) {   SetCenterPoint(center);  SetRadius(radius);  calcPoints();}void Hexagon::SetCenterPoint(Point center) {  itsCenter = center;  calcPoints();}int Hexagon::GetAltitude(){  return itsAltitude;}int Hexagon::GetRadius(){  return itsRadius;}void Hexagon::SetRadius(int radius) {  itsRadius = radius;  itsAltitude = int(float(sqrt(3)/2)*itsRadius);    calcPoints();  }void Hexagon::calcPoints(void){  itsPoints[0].SetX(itsCenter.GetX());  itsPoints[0].SetY(itsCenter.GetY() - itsRadius);    itsPoints[1].SetX(itsCenter.GetX() + itsAltitude);  itsPoints[1].SetY(itsCenter.GetY() - int(itsAltitude/2));    itsPoints[2].SetX(itsCenter.GetX() + itsAltitude);  itsPoints[2].SetY(itsCenter.GetY() + int(itsAltitude/2));    itsPoints[3].SetX(itsCenter.GetX());  itsPoints[3].SetY(itsCenter.GetY() + itsRadius);    itsPoints[4].SetX(itsCenter.GetX() - itsAltitude);  itsPoints[4].SetY(itsCenter.GetY() + int(itsAltitude/2));    itsPoints[5].SetX(itsCenter.GetX() - itsAltitude);  itsPoints[5].SetY(itsCenter.GetY() - int(itsAltitude/2));}void Hexagon::drawHex(bool drawInfo) {  TCHAR       szBuffer[50];  TEXTMETRIC tm;  GetTextMetrics (g_pHDC, &tm) ;  static int cyChar = tm.tmHeight + tm.tmExternalLeading;  static int cxChar = tm.tmAveCharWidth;    if(drawInfo){    TextOut( g_pHDC,  5, cyChar * 0, szBuffer, wsprintf(szBuffer, TEXT("Center Point: %d,%d"), itsCenter.GetX(),itsCenter.GetY() ));      TextOut( g_pHDC,  5, cyChar * 1, szBuffer, wsprintf(szBuffer, TEXT("Outer Circle Radius: %d"), itsRadius));      TextOut( g_pHDC,  5, cyChar * 2, szBuffer, wsprintf(szBuffer, TEXT("Inner Circle Radius: %d"), itsAltitude));     TextOut( g_pHDC,  5, cyChar * 3, szBuffer, wsprintf(szBuffer, TEXT("Point %d: %d,%d"), 0, itsPoints[0].GetX() , itsPoints[0].GetY()));    }  MoveToEx(g_pHDC,itsPoints[0].GetX(),itsPoints[0].GetY(), 0x00);  for(int i = 1;i<=5;i++) {    LineTo(g_pHDC,itsPoints[i].GetX(),itsPoints[i].GetY());    if(drawInfo){      TextOut( g_pHDC,  5, cyChar * (i + 3), szBuffer, wsprintf(szBuffer, TEXT("Point %d: %d,%d"), i, itsPoints[i].GetX() , itsPoints[i].GetY()));      }  }  LineTo(g_pHDC,itsPoints[0].GetX(),itsPoints[0].GetY());}bool Hexagon::IsInsideHex(int X, int Y){  int myBase = abs(X - itsCenter.GetX());  int myHeight = abs(Y - itsCenter.GetY());  int myHypotenuse = sqrt((myBase*myBase)+(myHeight*myHeight));  return (myHypotenuse <= itsAltitude);}Hexagon::~Hexagon() {}        


I did this using GDI so you will probably want to port the actual drawing mechanism over to DirectDraw or something. All the drawing code is handled in the DrawHex fuction. I also wanted a way to determine if the user clicked within the hexagon so I added the IsInHex function. It takes X and Y corrdinates and determines if the user clicked in the hex or not. I just created an array of hexagon objects and on mouseclick event loop through them and check the IsInHex function. Pretty simple. I'm kinda cheating because I wanted it to be fast, so if the user clicks really near the apex of the top or bottom of the hexagon it might not register a mouse click. Basicaly I'm just calculating if that click is in the "in-circle" of the hexagon. Math is not yet my strong suit (but I'm trying) and http://mathworld.wolfram.com has been invaluable to me on this project.

As a final note, passing a drawInfo parameter of true to the DrawHex function causes debugging information to be drawn on the screen. I used this when calling DrawHex from a mouse click event to view some debugging information. You will probably want want to strip this out. This code doesnt take into account for putting textures on the hexagon, but the point calculation seems solid, so you can replace the drawing code with whatever polygon drawing function your target API provides.

Ok, enough rambling.
~ chaosbob

Edited by - chaosbob on February 17, 2002 11:48:08 AM
well i have to say that this is alot more complete then what i have come up with so far
and looks alot more usefull
thank you for the reply.
I just found this tutorial on the GameDev site. It''s right up your alley I think. Mine too for that matter.

~chaosbob

This topic is closed to new replies.

Advertisement