Кажется, у меня возникли проблемы с рисованием правильной шестнадцатеричной сетки:
Как видите, шестиугольники немного смещены, хотя я считаю, что моя математика верна (некоторые из них проверены через http://www.redblobgames.com/grids/hexagons/).
Мой метод рисования заключается в том, чтобы начать с верхнего левого шестиугольника (первая плитка в первом ряду) и нарисовать этот ряд плиток. Затем для следующей строки имеется отрицательное смещение по X и положительное смещение по Y и т. д., пока не будет достигнута средняя строка, в которой смещения по X увеличиваются до 0:
private function drawHexGrid(inputGraphics:Graphics, inputPos:Point, inputGrid:HexGrid, inputTileSize:int):void {
var rootThree:Number = Math.sqrt(3); // seems like this will be used a lot
// total number of rows and also size of largest row (in tiles)
var totalRows:int = (2 * inputGrid.size) - 1;
// the other useful dimension of a hex tile
var triSize:Number = rootThree * 0.5 * inputTileSize;
var topLeft:Point = new Point(-(inputGrid.size - 1) * triSize, -(1.5 * (inputGrid.size - 1) * inputTileSize));
topLeft.x += inputPos.x;
topLeft.y += inputPos.y;
var currentPos:Point = topLeft.clone();
// step size between each tile and row
var xStep:Number = rootThree * inputTileSize;
var yStep:Number = triSize * rootThree;
var offsetDirection:int = -1;
var rowLimit:int = inputGrid.size;
var offsetAmount:int = 0; // offsetAmount goes 1 to n, then back to 0 again, used for calculating thw row offsets
var mazeTiles:Vector.<Tile> = inputGrid.getTiles();
var tileCounter:int = 0; // index to cycle through mazeTiles
for(var rowCount:int = 0; rowCount < totalRows; rowCount++){
currentPos.x = topLeft.x + (offsetAmount * rootThree / -2 * inputTileSize);
for(var counter:int = 0; counter < rowLimit; counter++){
drawHexTile(inputGraphics, currentPos.x, currentPos.y, inputTileSize, mazeTiles[tileCounter++]);
currentPos.x += xStep;
}
currentPos.y += yStep;
if(rowCount == (inputGrid.size - 1)){
offsetDirection *= -1;
}
rowLimit += offsetDirection * -1;
offsetAmount -= offsetDirection;
} // end of for loop
} // end of drawHexGrid()
Фактический рисунок каждого шестиугольника находится в этом цикле:
private function drawHexTile(inputGraphics:Graphics, inputX:int, inputY:int, inputSize:int, inputTile:Tile):void {
inputGraphics.lineStyle(0.1, 0, 1);
var convertToRadians:Number = Math.PI / 180;
// easier to draw by wall, since need to look up each wall and can set a starting degree without having to worry about the 'end degree'
// (since the end may not be 360 degrees if the starting degree is in the negatives or a high degree)
var degrees:int = -150; // starting wall is the top left wall of the hexagon tile
for(var counter:int = 0; counter < 6; counter++){
if(inputTile.walls[counter] == true){
inputGraphics.moveTo(inputX + (Math.cos(degrees * convertToRadians) * inputSize),
inputY + (Math.sin(degrees * convertToRadians) * inputSize));
inputGraphics.lineTo(inputX + (Math.cos((degrees + 60) * convertToRadians) * inputSize),
inputY + (Math.sin((degrees + 60) * convertToRadians) * inputSize));
}
degrees += 60;
}
} // end of drawHexTile() method
На первый взгляд, я думаю, что проблема связана с математической точностью с плавающей запятой, хотя я не уверен, как это исправить/улучшить.
Любые идеи?
Я знаю, что мой метод рисования приведет к большому количеству перекрывающихся линий, и на данный момент это нормально. Если это поможет, общий код предназначен для генератора шестиугольного лабиринта, который работает нормально, и поэтому его можно игнорировать, поскольку он не является частью проблемы.
И если это поможет, я храню шестиугольные плитки только в одном длинном массиве, проиндексированном следующим образом:
where n=4
0 1 2 3
4 5 6 7 8
9 10 11 12 13 14
15 16 17 18 19 20 21
22 23 24 25 26 27
28 29 30 31 32
33 34 35 36