public static List <PointyHexPoint> GetArc( this IMap3D <PointyHexPoint> map, PointyHexPoint origin, Facing startAngle, Facing endAngle, int minRadius, int maxRadius) { List <PointyHexPoint> result = new List <PointyHexPoint>(); for (int radius = minRadius; radius <= maxRadius; radius++) { PointyHexPoint cursor = origin + (startAngle.Offset() * radius); PointyHexPoint finish = origin + (endAngle.Offset() * radius); Facing facing = startAngle.CW(2); while (cursor != finish) { for (int step = 0; step < radius; step++) { result.Add(cursor); cursor += facing.Offset(); } facing = facing.CW(); } result.Add(cursor); } return(result); }
private static PointyHexGrid<int> tileMap; // Grid's "Hexagonal Array" containing an int corresponding to each type cell. Could be done with a simple 2D array for a square map. #endregion Fields #region Methods // Generate an Hexagonal map with Mathf.Perlin public static PointyHexGrid<int> GenerateHex(int width) { Debug.Log ("Time GenerationStart = " + Time.realtimeSinceStartup); tileMap = PointyHexGrid<int>.Hexagon(width); // Define tileMap from the inputted width of the hexagon float zoom = Random.Range (0.015f,0.17f); // Zoom in for "big smooth" peaks. Zoom out for "small noisy" peaks. Not the best description but gives an idea. Vector2 shift = new Vector2(Random.Range (-10,10), Random.Range (-10,10)); // play with this to move on the perlin map. Allow for infinite coherent map divided in chunks. // Step on each cell, calculate a noise value with Mathf.Perlin and define a type of cell according to hardcoded cell types for(int x = 0; x < (width*2) - 1; x++) // The for loops aren't stepping precisely on the hexagon shape but it works. Could be improved. { for(int y = 0; y < (width*2) - 1; y++) { Vector2 pos = zoom * (new Vector2(x,y)) + shift; // Position on the current cell on the perlin map, using value of shift/zoom float noise = 1.0f - Mathf.PerlinNoise(pos.x, pos.y); // Noise value at evaluated position on perlin map PointyHexPoint point = new PointyHexPoint(x - (width - 1), y - (width - 1)); // Calculate the grid's point that correspond to the current cell int _curTile = 0; // Default value // Define cell type according to noise value if (noise>0.90f) _curTile = (int)TileName.Mountain; else if (noise>0.80f) _curTile = (int)TileName.Hills; else if (noise>0.60f) _curTile = (int)TileName.BorealForest; else if (noise>0.50f) _curTile = (int)TileName.GrassLand; else if (noise>0.45f) _curTile = (int)TileName.Desert; else if (noise>0.30f) _curTile = (int)TileName.shallowWater; else _curTile = (int)TileName.deepWater; tileMap[point] = _curTile; // Set the current tile int on the tilemap } } Debug.Log ("Time GenerationFinish = " + Time.realtimeSinceStartup); return tileMap; }
/** * Gives a new point that represents the * reminder when the first point is divided * by the second point component-wise. The * division is integer division. * * @since 1.6 (Rect) * @since 1.7 (other) */ public PointyHexPoint Mod(PointyHexPoint otherPoint) { var x = GLMathf.Mod(X, otherPoint.X); var y = GLMathf.Mod(Y, otherPoint.Y); return(new PointyHexPoint(x, y)); }
/** * Gives a new point that represents the * first point multiplied by the second point * component-wise. * * @since 1.6 (Rect) * @since 1.7 (other) */ public PointyHexPoint Mul(PointyHexPoint otherPoint) { var x = X * otherPoint.X; var y = Y * otherPoint.Y; return(new PointyHexPoint(x, y)); }
private void UpdateAudibility() { Profiler.BeginSample("UpdateAudibility"); Profiler.BeginSample("Find Mobile"); PointyHexPoint mobLoc = mapMobile.location; Profiler.EndSample(); Profiler.BeginSample("Measure Distances"); foreach (var x in Controllers.map.mapGrid) { if (x.DistanceFrom(mobLoc) <= hearingRange) { Controllers.map.mapGrid[x].audibility = Audibility.audible; } else { Controllers.map.mapGrid[x].audibility = Audibility.inaudible; } } Profiler.EndSample(); Profiler.EndSample(); }
private void moveToTarget(PointyHexPoint pos) { List<PathPoint> path = new List<PathPoint> (); Utils.findRandomPath (target.Point, Point, Direction, attributes.speed, path, mc.Grid); int pathSize = Mathf.Min (attributes.speed, path.Count); Vector3[] plist = new Vector3[attributes.speed]; int count = 0; foreach (PathPoint p in path) { plist [count] = mc.Map [p.pos]; count += 1; if (count >= pathSize) { break; } } shipObj.transform.DOPath (plist, 1f, PathType.Linear, PathMode.TopDown2D, 10, Color.cyan) .OnWaypointChange((idx) => { if (idx < path.Count) { Direction = path[idx].dir; showDirection(); } }) .OnComplete (() => { currentPos = path[count - 1].pos; direction = path[count - 1].dir; showDirection(); fireAt(target); mc.turnOver(this); }); }
public static IEnumerable <PointyHexPoint> GetEdgeFaces(PointyHexPoint point) { var color = point.GetColor2_4(); var faces = new PointList <PointyHexPoint>(); switch (color) { case 0: //error! break; case 1: faces.Add(point + PointyHexPoint.East); faces.Add(point + PointyHexPoint.West); break; case 2: faces.Add(point + PointyHexPoint.SouthWest); faces.Add(point + PointyHexPoint.NorthEast); break; case 3: faces.Add(point + PointyHexPoint.SouthEast); faces.Add(point + PointyHexPoint.NorthWest); break; } return(faces); }
public PointyHexShapeInfo <TCell> Hexagon(int side) { var storageSize = 2 * side - 1; var storageBottomLeft = new PointyHexPoint(1 - side, 1 - side); return(Shape(storageSize, storageSize, x => IsInsideHex(x, side), storageBottomLeft)); }
/** * Gives a new point that represents the * first point divided by the second point * component-wise. The division is integer * division. * * @since 1.6 (Rect) * @since 1.7 (other) */ public PointyHexPoint Div(PointyHexPoint otherPoint) { var x = Mathi.Div(X, otherPoint.X); var y = Mathi.Div(Y, otherPoint.Y); return(new PointyHexPoint(x, y)); }
public PointyHexShapeInfo <TCell> ThinRectangle(int width, int height) { int storageWidth = width + Mathi.Div(height - 1, 2); int storageHeight = height; var storageBottomLeft = new PointyHexPoint(-Mathi.Div(height - 1, 2), 0); return(Shape(storageWidth, storageHeight, x => IsInsideThinRectangle(x, width, height), storageBottomLeft)); }
private static bool IsInsideXYParallelogram(PointyHexPoint point, int width, int height) { return ((point.X >= 0) && (point.X < width) && (point.Y >= 0) && (point.Y < height)); }
/** Rotates a shape 180 degrees around the edge shared by the two given points. The two points must be neighbors. */ public static IEnumerable<PointyHexPoint> Rotate180About( IEnumerable<PointyHexPoint> shape, PointyHexPoint p1, PointyHexPoint p2) { var translation = p1.Translate(p2); var correction = translation.Subtract(translation.Rotate180()).ScaleDown(2); return TransformShape<PointyHexPoint>(shape, point => point.Rotate180().Translate(correction)).ToList(); }
private static bool IsInsideThinRectangle(PointyHexPoint point, int width, int height) { int startX = -(GLMathf.Div(point.Y, 2)); return (point.X >= startX && point.X + GLMathf.Mod(point.Y, 2) < startX + width && point.Y >= 0 && point.Y < height); }
private static bool IsInsideFatRectangle(PointyHexPoint point, int width, int height) { int startX = -(Mathi.Div(point.Y, 2)); return (point.X >= startX - Mathi.Mod(point.Y, 2) && point.X < startX + width && point.Y >= 0 && point.Y < height); }
public void Ini(int _owner, int _size, int _population, PointyHexPoint _pointCity) { owner = _owner; size = _size; population = _population; pointCity = _pointCity; points.Add(_pointCity); List<string> AllNames = new List<string>() {"Tristram", "Gerudo", "Kakariko", "Xel'naga", "Athkatla", "San Andreas", "Reach", "Pallet Town", "Rapture", "City17" }; name = AllNames[Random.Range (0,AllNames.Count)]; }
public IEnumerable <GridPoint2> GetGridPath() { var path = Grids2.Algorithms.AStar( walkableGrid, start, goal, (p, q) => PointyHexPoint.ManhattanNorm(p - q), c => walkableGrid[c].IsWalkable, PointyHexPoint.GetOrthogonalNeighbors, (p, q) => 1); return(path); }
public IEnumerable <GridPoint2> GetWeightedPath() { var path = Grids2.Algorithms.AStar( walkableGrid, start, goal, (p, q) => PointyHexPoint.ManhattanNorm(p - q) * WalkableCell.MinCost, c => walkableGrid[c].IsWalkable, PointyHexPoint.GetOrthogonalNeighbors, GetMovementCost); return(path); }
public static List <PointyHexPoint> GetCircle( this IMap3D <PointyHexPoint> map, PointyHexPoint origin, int minRadius, int maxRadius) { List <PointyHexPoint> result = new List <PointyHexPoint>(); for (int radius = minRadius; radius <= maxRadius; radius++) { } return(result); }
public void showPath(PointyHexPoint pos) { clearPreviousPath (); targetPos = pos; foreach (PointyHexPoint p in Algorithms.AStar(mc.Grid, currentPos, pos)) { // Only hightlight reachable path if (path.Count < attributes.speed) { pointOn (p); } else { pointRed (p); } path.Add (p); } }
public void Update() { if (Input.GetMouseButtonDown(0)) { Vector3 mousePosition = Input.mousePosition; Vector2 worldPosition = GridBuilderUtils.ScreenToWorld(root, mousePosition); PointyHexPoint hexPoint = map[worldPosition]; if (grid.Contains(hexPoint)) { grid[hexPoint].HighlightOn = !grid[hexPoint].HighlightOn; } } }
public override void handleClick(PointyHexPoint pos) { GenericShip enemy = mc.getEnemyShip (); if (pos.Equals (enemy.Point)) { fireAt (enemy); return; } if (pos.Equals (currentPos)) { return; } // If clicked on the same target point. if (targetPos.Equals (pos)) { moveToTarget (); return; } showPath (pos); }
private void InitPattern3() { var randomPoints = Grid.Points.SampleRandom(2); var pattern = new HashSet <GridPoint2>(); int symmetry = Random.Range(0, 3); foreach ( var pointyHexPoints in randomPoints .Select(point1 => Grid.Points.Where(p => PointyHexPoint.HexNorm((p - point1)) <= 3).SampleRandom(2)) .Select(randomGroup => randomGroup as IList <GridPoint2> ?? randomGroup.ToList())) { pattern.AddRange(pointyHexPoints); switch (symmetry) { case Symmetry6: pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate60)); pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate120)); pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate180)); pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate240)); pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate300)); break; case Symmetry3: pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate120)); pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate240)); break; case Symmetry2: pattern.AddRange(pointyHexPoints.Select <GridPoint2, GridPoint2>(PointyHexPoint.Rotate180)); break; } } foreach (var point in pattern) { ToggleCellAt(point); } }
public override void Perform() { Vector3 oldPos = actor.mapMobile.transform.position; Vector3 newPos = Controllers.map.CellAt(destination).transform.position; PointyHexPoint dst = destination; Controllers.map.UnplaceMobile(actor.mapMobile); Controllers.map.PlaceMobile(actor.mapMobile, dst); actor.ct += actor.mapMobile.CostToEnter(Controllers.map.CellAt(dst)); if (actor.mapMobile.visibility == Visibility.visible) { MoveAnimation newAnimation = actor.mapMobile.gameObject.AddComponent <MoveAnimation>(); newAnimation.oldPos = oldPos; newAnimation.newPos = newPos; newAnimation.maxTime = moveTime; Controllers.turn.RegisterAnimation(newAnimation); } }
private IEnumerable <GridPoint2> Transform(IEnumerable <GridPoint2> points, GridPoint2 offset, int rotationIndex, bool reverse) { var list = new List <GridPoint2>(); var newOffset = offset; for (var i = 0; i < depth; i++) { newOffset = newOffset.Mul(rotation); } var center = GridPoint2.Zero; for (var i = 0; i < depth; i++) { center = center.Mul(rotation); center += new GridPoint2(0, 1); } foreach (var point in points) { var newPoint = point - center; for (var i = 0; i < rotationIndex; i++) { newPoint = PointyHexPoint.Rotate60(newPoint); } newPoint += newOffset + center; list.Add(newPoint); } if (reverse) { list.Reverse(); } return(list); }
public void Update() { if (Input.GetMouseButtonDown(0)) { // If you use a different GUI system, you will probably need a // custom version of this function. // This assumes your camera is orthographic. For perspective cameras, // you must use a ray casting method instead. Vector3 worldPosition = GridBuilderUtils.ScreenToWorld(root, Input.mousePosition); // Calculates the grid point that corresponds to the given world coordinate. PointyHexPoint point = map[worldPosition]; // The point may in fact lie outside the grid as we defined it when we built it. // So we first check whether the grid contains the point... if (grid.Contains(point)) { //... and toggle the highlight of the cell grid[point].HighlightOn = !grid[point].HighlightOn; } } }
/** Rotates a shape 120 degrees around the vertice shared by the three given points. The three points must form a close triangle (they must share a vertex). */ public static IEnumerable<PointyHexPoint> Rotate120About( IEnumerable<PointyHexPoint> shape, PointyHexPoint p1, PointyHexPoint p2, PointyHexPoint p3) { /* If t = (p1 + p2 + p3)/3, then the result is p => (p - t).Rotate120() + t. This can be rewritten p => p.Rotate120() - t.Rotate120() + t = p.Rotate120() (T - T.Rotate120())/3, where T = p1 + p2 + p3. This is what this method calculates. This is done so that all coordinates in intermediatary calculations stay integers. */ var translation = p1.Translate(p2.Translate(p3)); var correction = translation.Subtract(translation.Rotate120()).ScaleDown(3); return TransformShape(shape, point => point.Rotate120().Translate(correction)).ToList(); }
/** * Gives a coloring of the grid such that * if a point p has color k, then all points * p + m[ux, 0] + n[vx, vy] have the same color * for any integers a and b. * * More information anout grid colorings: * http://gamelogic.co.za/2013/12/18/what-are-grid-colorings/ * * @since 1.7 */ public int __GetColor__ReferenceImplementation(int ux, int vx, int vy) { var u = new PointyHexPoint(ux, 0); var v = new PointyHexPoint(vx, vy); int colorCount = u.PerpDot(v); float a = PerpDot(v) / (float)colorCount; float b = -PerpDot(u) / (float)colorCount; int m = Mathi.FloorToInt(a); int n = Mathi.FloorToInt(b); int baseVectorX = m * u.X + n * v.X; int baseVectorY = n * u.Y + n * v.Y; int offsetX = Mathi.Mod(X - baseVectorX, ux); int offsetY = Y - baseVectorY; int colorIndex = Mathi.FloorToInt(offsetX + offsetY * ux); return(colorIndex); }
public void Update() { if (Input.GetMouseButtonDown(0)) { Vector3 worldPosition = GridBuilderUtils.ScreenToWorld(Input.mousePosition); PointyHexPoint hexPoint = map[worldPosition]; if (grid.Contains(hexPoint)) { if (grid[hexPoint] != null) { grid[hexPoint].gameObject.SetActive(!grid[hexPoint].gameObject.activeInHierarchy); } } } if (Input.GetKey(KeyCode.UpArrow)) { cam.transform.position = cam.transform.position + Vector3.up * 10f; } if (Input.GetKey(KeyCode.DownArrow)) { cam.transform.position = cam.transform.position + Vector3.down * 10f; } if (Input.GetKey(KeyCode.LeftArrow)) { cam.transform.position = cam.transform.position + Vector3.left * 10f; } if (Input.GetKey(KeyCode.RightArrow)) { cam.transform.position = cam.transform.position + Vector3.right * 10f; } }
/** * This is a norm defined on the point, such that `p1.Difference(p2).Abs()` is equal to * `p1.DistanceFrom(p2)`. */ public PointyHexPoint Translate(PointyHexPoint translation) { return(new PointyHexPoint(x + translation.X, y + translation.Y)); }
// Get a random cell that is contained by the grid private Cell GetRandomCell() { Cell _cell; int x = Random.Range (-(width-1),width-1); int y = Random.Range (-(width-1),width-1); PointyHexPoint point = new PointyHexPoint(x,y); // Make sure the random cell is not outside of the hexagonal grid while(!grid.Contains(point)) { x = Random.Range (-(width-1),width-1); y = Random.Range (-(width-1),width-1); point = new PointyHexPoint(x,y); } return grid[point]; }
/** * @since 1.7 */ public int PerpDot(PointyHexPoint other) { return(x * other.Y - y * other.x); }
/** * @version1_8 */ public InspectableVectorPoint(PointyHexPoint point) { x = point.X; y = point.Y; }
public void instantiate(PointyHexPoint pos) { currentPos = pos; shipObj = GameObject.Instantiate (attributes.shipPreb); shipObj.transform.position = mc.Map [currentPos]; }
private void pointOff(PointyHexPoint p) { mc.Grid [p].onDefault (); }
//Instantiate the cell and initialize its values private void CreateCell(PointyHexPoint point) { //Instantiate the cell Cell cell = Instantiate(cellPrefab); Vector3 worldPoint = map[point]; cell.transform.parent = root.transform; cell.transform.localScale = Vector3.one; cell.transform.localPosition = worldPoint; cell.transform.name = "hexCell(" + point.X + "," + point.Y + ")"; // Set cell's value cell.SetTile(tileMap[point]); cell.point = point; grid[point] = cell; }
/** * The lattice distance from this point to the other. */ public int DistanceFrom(PointyHexPoint other) { return(Subtract(other).Magnitude()); }
private void pointOn(PointyHexPoint p) { mc.Grid [p].onBlue (); }
/** @version1_8 */ public InspectableVectorPoint(PointyHexPoint point) { x = point.X; y = point.Y; }
public bool Equals(PointyHexPoint other) { bool areEqual = (x == other.X) && (y == other.Y); return(areEqual); }
/** * Subtracts the other point from this point, and returns the result. */ public PointyHexPoint Subtract(PointyHexPoint other) { return(new PointyHexPoint(x - other.X, y - other.Y)); }
public PointyHexPoint MoveBy(PointyHexPoint translation) { return(Translate(translation)); }
public PointyHexPoint MoveBackBy(PointyHexPoint translation) { return(Translate(translation.Negate())); }
private void moveToTarget() { int pathSize = Mathf.Min (attributes.speed + 1, path.Count); Vector3[] plist = new Vector3[pathSize]; int count = 0; foreach (PointyHexPoint p in path) { plist [count] = mc.Map [p]; count += 1; if (count >= pathSize) { targetPos = p; break; } } shipObj.transform.DOPath (plist, 1f, PathType.Linear, PathMode.TopDown2D, 10, Color.cyan) .OnComplete (() => { clearPreviousPath (); currentPos = targetPos; }); }
/** * @since 1.7 */ public int Dot(PointyHexPoint other) { return(x * other.X + y * other.Y); }
private void pointRed(PointyHexPoint p) { mc.Grid [p].onRed (); }
public virtual void handleClick(PointyHexPoint pos) { }