My new project is one in which the player takes turns against the computer fighting across a hexagonal grid system. As the player traverses the game world, he/she will hit triggers that reveal the hexagonal grid for a fight, sending the player and nearby enemies to respective positions in the game world.

I quickly realised that creating the hexagonal grid each time would be a chore, because the way I’m doing it currently involves detailing the up to 6 connecting nodes for each node. So today I’ve been focusing on building a simple-ish tool that will automatically generate a hexagonal grid for me that I then merely need to tweak.

All I need to do to create a grid is to set a base name (say TowerFight or BeachFightA, etc.) then the X grid width and Y grid depth/height and click on the terrain (or at the moment, a button) to generate the grid.

Curious about the TorqueScript used to generate the grid? There’s still some small changes I want to make, but oh what the hell:

Note – The simgroup is simply a way of grouping together stuff in a mission file, so in the code below, I’m creating a simgroup to store all the elements that go into creating the hex grid. I can then select that simgroup folder to select everything sub foldered within it. Then I can rotate, move (etc) the whole grid with ease.

It’s more readable here: http://pastebin.com/gQVPVdRN

// concatenation of CombatHexGridNameTextField.text + X Num + Y Num
// X Num and Y Num change depending on if we’re filling the node name or
//connectingNodeNW
//connectingNodeNN
//connectingNodeNE
//connectingNodeSW
//connectingNodeSS
//connectingNodeSE

//xPosTextField.text and yPosTextField.text
//CombatHexGridNameTextField.text

//x = 1
//connectingNodeNW = -1;
//connectingNodeSW = -1;

//x = xPosTextField.text
//connectingNodeNE = -1;
//connectingNodeSE = -1;

//y = 1
//connectingNodeNN = -1;

//y = 1 and x = odd number
//connectingNodeNW = -1;
//connectingNodeNN = -1;
//connectingNodeNE = -1;

function BeginHexCreation()
{
   %simGroupName = CombatHexGridNameTextField.getText();
   %obj = new SimGroup(%simGroupName)
      {
         canSave = “1”;
         canSaveDynamicFields = “1”;
      };
      MissionGroup.add(%obj);

   %xGridMaxPos = xPosTextField.getValue();
   %yGridMaxPos = yPosTextField.getValue();

   %hexOffsetValue = 0;

   %combatNodeXWorldPos = 20;
   %combatNodeYWorldPos = 20;
   %variableCombatNodeYWorldPos = %combatNodeYWorldPos;
   %combatNodeZWorldPos = 240.1;
   %combatNodePosition = %combatNodeXWorldPos SPC %CombatNodeYWorldPos SPC %combatNodeZWorldPos;
   %hexOffset = true;

   %ORIGINcombatNodeXWorldPos = %combatNodeXWorldPos;

   %xGridPos = 1;
   %yGridPos = 1;

   while(%yGridPos<=%yGridMaxPos)
   {
   %hexOffset = true;
   %combatNodeXWorldPos = %ORIGINcombatNodeXWorldPos;

   while(%xGridPos<=%xGridMaxPos)
   {

   %newCombatNodeName = CombatHexGridNameTextField.getValue() @ “X” @ %xGridPos @ “Y” @ %yGridPos;

   //Turns out the connecting node names are different depending on if %xGridPos is odd or even
   if(!((%xGridPos /2)==1))
   {
      %connectingNodeNWName = CombatHexGridNameTextField.text @ “X” @ %xGridPos-1 @ “Y” @ %yGridPos-1;
      %connectingNodeNNName = CombatHexGridNameTextField.text @ “X” @ %xGridPos @ “Y” @ %yGridPos-1;
      %connectingNodeNEName = CombatHexGridNameTextField.text @ “X” @ %xGridPos+1 @ “Y” @ %yGridPos-1;
      %connectingNodeSWName = CombatHexGridNameTextField.text @ “X” @ %xGridPos-1 @ “Y” @ %yGridPos;
      %connectingNodeSSName = CombatHexGridNameTextField.text @ “X” @ %xGridPos @ “Y” @ %yGridPos+1;
      %connectingNodeSEName = CombatHexGridNameTextField.text @ “X” @ %xGridPos+1 @ “Y” @ %yGridPos;
   }
   else
   {
      %connectingNodeNWName = CombatHexGridNameTextField.text @ “X” @ %xGridPos-1 @ “Y” @ %yGridPos;
      %connectingNodeNNName = CombatHexGridNameTextField.text @ “X” @ %xGridPos @ “Y” @ %yGridPos-1;
      %connectingNodeNEName = CombatHexGridNameTextField.text @ “X” @ %xGridPos+1 @ “Y” @ %yGridPos;
      %connectingNodeSWName = CombatHexGridNameTextField.text @ “X” @ %xGridPos-1 @ “Y” @ %yGridPos+1;
      %connectingNodeSSName = CombatHexGridNameTextField.text @ “X” @ %xGridPos @ “Y” @ %yGridPos+1;
      %connectingNodeSEName = CombatHexGridNameTextField.text @ “X” @ %xGridPos+1 @ “Y” @ %yGridPos+1;
   }

   if(%xGridPos==1) //This if prevents the offset triggering when it shouldn’t be due to odd numbered width
   {
      %hexOffsetValue = 0;
   }
   %variableCombatNodeYWorldPos = %combatNodeYWorldPos + %hexOffsetValue;
   %combatNodePosition = %combatNodeXWorldPos SPC %variableCombatNodeYWorldPos SPC %combatNodeZWorldPos;

   new StaticShape(%newCombatNodeName) {
         dataBlock = “CombatNode”;
         parentGroup = %simGroupName;
         position = %combatNodePosition;
         rotation = “1 0 0 0”;
         scale = “1 1 1”;
         canSave = “1”;
         canSaveDynamicFields = “1”;
            connectingNodeNW = %connectingNodeNWName;
            connectingNodeNN = %connectingNodeNNName;
            connectingNodeNE = %connectingNodeNEName;
            connectingNodeSW = %connectingNodeSWName;
            connectingNodeSS = %connectingNodeSSName;
            connectingNodeSE = %connectingNodeSEName;
            occupant = “None”;
      };
   echo(“Created at X: ” @ %combatNodeXWorldPos @ ” Y: ” @ %variableCombatNodeYWorldPos);

   if(%hexOffset$=true)
   {
      %hexOffset = false;
      %hexOffsetValue = -2;
   }
   else
   {
      %hexOffset = true;
      %hexOffsetValue = 0;
   }

   %combatNodeXWorldPos = %combatNodeXWorldPos + 3;
   %xGridPos = %xGridPos +1;

   }
   %combatNodeYWorldPos = %combatNodeYWorldPos -4;   

   %xGridPos = 1;
   %yGridPos = %yGridPos +1;

   }
}

Advertisements