
This example is the famous Lights Out game on a hex grid. All the patterns are procedurally generated.
[button url=”https://gamelogic.co.za/examples/grids/monster-hex/”]PLAY GAME[/button]
Note: You need the Unity Web Plugin to play this example.
Main Game Logic
using System;
using System.Linq;
using System.Collections.Generic;
using UnityEngine;
using Gamelogic.Grids;
public class LightsOutHex : GLMonoBehaviour, IResetable
{
private const int Symmetry2 = 0;
private const int Symmetry3 = 1;
private const int Symmetry6 = 2;
public Cell cellPrefab;
public GameObject root;
private Vector2 hexDimensions = new Vector2(74, 84);
private PointyHexGrid grid;
private IMap3D map;
private Color offColor = ExampleUtils.colors[4];
private Color onColor = ExampleUtils.colors[6];
public void Start()
{
Reset();
}
public void Update()
{
if(Input.GetMouseButtonDown(0))
{
Vector3 worldPosition = ExampleUtils.ScreenToWorld_NGUI(root, Input.mousePosition);
PointyHexPoint hexPoint = map[worldPosition];
if(grid.Contains(hexPoint))
{
ToggleCellAt(hexPoint);
}
}
}
public void Reset()
{
root.transform.DestroyChildren();
BuildGrid();
InitGame();
}
private void BuildGrid()
{
grid = PointyHexGrid.Hexagon(5);
map = new PointyHexMap(hexDimensions)
.WithWindow(ExampleUtils.ScreenRect)
.AlignMiddelCenter(grid)
.AnchorCellMiddelCenter()
.To3DXY();
foreach(PointyHexPoint point in grid)
{
Cell cell = Instantiate(cellPrefab);
Vector3 worldPoint = map[point];
cell.transform.parent = root.transform;
cell.transform.localScale = Vector3.one;
cell.transform.localPosition = worldPoint;
cell.SetColor(offColor);
cell.SetText("");
grid[point] = cell;
}
}
private void InitGame()
{
int pattern = UnityEngine.Random.Range(0, 3);
switch(pattern)
{
case 0:
InitPattern1();
break;
case 1:
InitPattern2();
break;
case 2:
InitPattern1();
InitPattern2();
break;
}
if(grid.All(p => !grid[p].HighlightOn))
{
Reset();
}
}
private void InitPattern2()
{
int start = UnityEngine.Random.Range(0, 3);
int end = UnityEngine.Random.Range(start, 3);
int symmetry = UnityEngine.Random.Range(0, 3);
switch(symmetry)
{
case Symmetry6:
for(int i = start; i <= end; i++)
{
ToggleCellAt((PointyHexPoint.East + PointyHexPoint.NorthEast) * i);
ToggleCellAt((PointyHexPoint.West + PointyHexPoint.SouthWest) * i);
ToggleCellAt((PointyHexPoint.NorthEast + PointyHexPoint.NorthWest) * i);
ToggleCellAt((PointyHexPoint.SouthWest + PointyHexPoint.SouthEast) * i);
ToggleCellAt((PointyHexPoint.NorthWest + PointyHexPoint.West) * i);
ToggleCellAt((PointyHexPoint.SouthEast + PointyHexPoint.East) * i);
}
break;
case Symmetry3:
for(int i = start; i <= end; i++)
{
ToggleCellAt((PointyHexPoint.East + PointyHexPoint.NorthEast) * i);
ToggleCellAt((PointyHexPoint.SouthWest + PointyHexPoint.SouthEast) * i);
ToggleCellAt((PointyHexPoint.NorthWest + PointyHexPoint.West) * i);
}
break;
case Symmetry2:
for(int i = start; i <= end; i++)
{
ToggleCellAt((PointyHexPoint.East + PointyHexPoint.NorthEast) * i);
ToggleCellAt((PointyHexPoint.West + PointyHexPoint.SouthWest) * i);
}
break;
}
}
private void InitPattern1()
{
int start = UnityEngine.Random.Range(0, 5);
int end = UnityEngine.Random.Range(start, 5);
int symmetry = UnityEngine.Random.Range(0, 3);
switch(symmetry)
{
case Symmetry6:
for(int i = start; i <= end; i++)
{
ToggleCellAt(PointyHexPoint.East * i);
ToggleCellAt(PointyHexPoint.West * i);
ToggleCellAt(PointyHexPoint.NorthEast * i);
ToggleCellAt(PointyHexPoint.SouthWest * i);
ToggleCellAt(PointyHexPoint.NorthWest * i);
ToggleCellAt(PointyHexPoint.SouthEast * i);
}
break;
case Symmetry3:
for(int i = start; i <= end; i++)
{
ToggleCellAt(PointyHexPoint.East * i);
ToggleCellAt(PointyHexPoint.SouthWest * i);
ToggleCellAt(PointyHexPoint.NorthWest * i);
}
break;
case Symmetry2:
for(int i = start; i <= end; i++)
{
ToggleCellAt(PointyHexPoint.East * i);
ToggleCellAt(PointyHexPoint.West * i);
}
break;
}
}
private void ToggleCellAt(PointyHexPoint hexPoint)
{
foreach(PointyHexPoint point in grid.GetNeighbors(hexPoint))
{
grid[point].HighlightOn = !grid[point].HighlightOn;
grid[point].SetColor(grid[point].HighlightOn ? onColor : offColor);
}
}
}
Generic Cell Class
using System.Linq;
using UnityEngine;
public class Cell : CSMonoBehaviour
{
public string[] spriteNames;
protected UISprite image;
protected UISprite highlight;
protected UILabel spriteText;
private bool highlightOn;
public bool HighlightOn
{
set
{
highlightOn = value;
highlight.enabled = value;
}
get
{
return highlightOn;
}
}
public void Awake()
{
image = GetComponentsInChildren().First(x => x.name == "Image");
highlight = GetComponentsInChildren().First(x => x.name == "Highlight");
spriteText = GetComponentInChildren();
HighlightOn = false;
}
public void SetColor(Color color)
{
image.color = (color);
}
public void SetText(string newText)
{
spriteText.text = newText;
}
public void SetFrame(int frameIndex)
{
image.spriteName = spriteNames[frameIndex];
image.MakePixelPerfect();
}
public void SetHighlightFrame(int frameIndex)
{
highlight.spriteName = spriteNames[frameIndex];
image.MakePixelPerfect();
}
}
