Pipes (Jungle Altar)
This is a version of the game Pipes with a mayan theme.
PLAY GAMENote: You need the Unity Web Plugin to play this example.
Main Game Logic
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 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 |
public class Pipes : CSMonoBehaviour { private readonly PointyHexPoint offset = new PointyHexPoint(1, 1); /* In this example each tile image has a binary presentation with six digits that correponds to the six edges of the hex and indicate whether edges have pipes through them or not. This arrays maps the image number to the sprite frame index. */ private int[] frameIndices = { 0, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, -1, 7, -1, -1, -1, 8, -1, 9, -1, 10, -1, -1, -1, 11, -1, -1, -1, 12, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 13 }; public PipesCell cellPrefab; public GameObject root; private Vector2 hexDimensions = new Vector2(74, 65); private PointyHexGrid grid; private IMap3D map; private Rect screenRect; private int screenshotCount; public void Start() { UnityEngine.Random.seed = 5; BuildGrid(); RandomRotateCells(); UpdateHighlights(); } private void BuildGrid() { grid = PointyHexGrid.Hexagon(width); map = new PointyHexMap(hexDimensions) .WithWindow(ExampleUtils.ScreenRect) .AlignMiddelCenter(grid) .AnchorCellMiddelCenter() .To3DXY(); var edgeGrid = grid.MakeEdgeGrid(); foreach(PointyRhombPoint point in edgeGrid) { edgeGrid[point] = UnityEngine.Random.Range(0, 2); } foreach (PointyHexPoint point in grid) { PipesCell cell = Instantiate (cellPrefab); Vector3 rPoint = map[point]; cell.transform.parent = root.transform; cell.transform.localScale = Vector3.one; cell.transform.localPosition = rPoint; cell.transform.SetRotationZ(-30); grid[point] = cell; SetCellSprite(edgeGrid, point, cell); } } private void RandomRotateCells() { foreach (PointyHexPoint point in grid) { int rotationCount = UnityEngine.Random.Range (0, 6); for (int i = 0; i < rotationCount; i++) { grid [point].RotateCW(); } } } private void UpdateHighlights() { foreach (var point in grid) { UpdateHighlight(point); } } private void SetCellSprite(IGrid<int, pointyrhombpoint=""> edgeGrid, PointyHexPoint point, PipesCell cell) { var edges = from edgePoint in point.GetEdges() select edgeGrid [edgePoint]; int imageIndex = edges.Reverse().Aggregate ((x, y) => (x << 1) + y); // Because images are flat hex, not pointy, and we want them pointy float zRotation = -30; for (int i = 0; i < 6; i++) { if (frameIndices [imageIndex] != -1) //we found it { //so we can use it cell.SetFrame (frameIndices[imageIndex]); cell.Image.transform.SetRotationZ (zRotation); break; } //While we cannot find the sprite, transform and check again zRotation += 60; imageIndex = RotateEdgeNumberClockWise (imageIndex); } cell.EdgeData = edges.ToList(); } public int RotateEdgeNumberClockWise(int edge) { return ((edge & 1) << 5) + (edge >> 1); } public int RotateEdgeNumberCounterClockWise(int edge) { return ((edge << 1) & 63) + (edge >> 5); } public void Update() { if(Input.GetMouseButtonDown(0)) { Vector3 worldPosition = ExampleUtils.ScreenToWorld(root, Input.mousePosition); PointyHexPoint hexPoint = map[worldPosition]; if(grid.Contains(hexPoint)) { grid[hexPoint].RotateCW(); UpdateHighlight(hexPoint); foreach(var neighbor in grid.GetNeighbors(hexPoint)) { UpdateHighlight(neighbor); } } } else if(Input.GetMouseButtonDown(1)) { Vector3 worldPosition = ExampleUtils.ScreenToWorld(root, Input.mousePosition); PointyHexPoint hexPoint = map[worldPosition]; if(grid.Contains(hexPoint)) { grid[hexPoint].RotateCCW(); UpdateHighlight(hexPoint); foreach(var neighbor in grid.GetNeighbors(hexPoint)) { UpdateHighlight(neighbor); } } } if(HasGameFinished()) { Debug.Log ("Game Ended!"); } } public bool HasGameFinished() { return grid.All(IsClosed); } public void UpdateHighlight(PointyHexPoint point) { grid[point].HighlightOn = IsClosed(point); } public bool IsClosed(PointyHexPoint point) { var neighbors = grid.GetAllNeighbors(point).ToList(); bool isClosed = true; //We use for loop so that we can use the index in the access operation below for (int i = 0; i < neighbors.Count(); i++) { if (grid.Contains(neighbors[i])) { //(i + 3) % 6 is the opposite neighbor //Here we abuse the fact that neighbors are returned in (anti-clockwise) order. if (grid[point].EdgeData[i] != grid[neighbors[i]].EdgeData[(i+3)%6]) { isClosed = false; } } } return isClosed; } } |
Pipes Cell
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 37 38 39 40 41 42 43 44 45 46 47 48 |
using System.Linq; using System.Collections.Generic; using UnityEngine; public class PipesCell : Cell { private List edgeData; public List EdgeData { get { return edgeData; } set { edgeData = value; } } public MonoBehaviour Image { get { return image; } } public void RotateCW() { var newEdgeData = edgeData.ButFirst().ToList(); newEdgeData.Add(edgeData.First()); edgeData = newEdgeData; image.transform.RotateAroundZ(-60); } public void RotateCCW() { List newEdgeData = edgeData.ButLast().ToList(); newEdgeData.Insert(0, edgeData.Last()); edgeData = newEdgeData; image.transform.RotateAroundZ(60); } } |