using System;
using System.Collections.Generic;
using System.Linq;
using UnityEngine;
using Gamelogic.Grids;
public class BlocksSlider : GLMonoBehaviour
{
private enum BlockType
{
Vertical,
Horizontal
}
private class Block
{
private Dictionary tileObjects;
private int blockID;
public int ID
{
get
{
return blockID;
}
}
public IEnumerable TilePoints
{
get
{
return tileObjects.Keys;
}
}
public IEnumerable TileObjects
{
get
{
return tileObjects.Values;
}
}
public RectPoint CurrentPosition
{
get;
set;
}
public Block(int blockID)
{
tileObjects = new Dictionary();
this.blockID = blockID;
}
//All tile points are relative to CurrentPosition
public void AddTile(RectPoint tilePoint, Cell tileObject)
{
tileObjects[tilePoint] = tileObject;
}
public void UpdateTilePositions(IMap3D map)
{
foreach (RectPoint tilePoint in TilePoints)
{
tileObjects[tilePoint].transform.localPosition = map[CurrentPosition + tilePoint];
}
}
public void Clear()
{
tileObjects.Clear();
}
}
public GameObject uiRoot;
public Cell cellPrefab;
private RectGrid tileGrid;
private RectGrid blocksGrid;
private IMap3D map;
private Block currentBlock;
private int currentBlockIndex;
private List blocks;
private RectPoint winPosition;
private Dictionary keysToDirections = new Dictionary
{
{KeyCode.UpArrow, RectPoint.North},
{KeyCode.LeftArrow, RectPoint.West},
{KeyCode.DownArrow, RectPoint.South},
{KeyCode.RightArrow, RectPoint.East},
};
public void Start()
{
BuildPuzzle();
}
private void Update()
{
if (Input.GetMouseButtonDown(0))
{
Vector3 worldPosition = ExampleUtils.ScreenToWorld_NGUI(uiRoot, Input.mousePosition);
RectPoint rectPosition = map[worldPosition];
if (tileGrid.Contains(rectPosition))
{
if (blocksGrid[rectPosition] != null)
{
SetHighlight(currentBlock, false);
currentBlock = blocksGrid[rectPosition];
SetHighlight(currentBlock, true);
}
}
}
foreach (KeyCode key in keysToDirections.Keys)
{
if (Input.GetKeyDown(key))
{
Debug.Log(key);
RectPoint newPoint = currentBlock.CurrentPosition + keysToDirections[key];
if (CanOccupy(currentBlock, newPoint))
{
RemoveTile(currentBlock);
PlaceTile(currentBlock, newPoint);
currentBlock.UpdateTilePositions(map);
}
}
}
if (Input.GetKeyDown(KeyCode.Tab))
{
SetHighlight(currentBlock, false);
if (Input.GetKey(KeyCode.LeftShift) || Input.GetKey(KeyCode.RightShift))
{
currentBlockIndex--;
}
else
{
currentBlockIndex++;
}
currentBlockIndex = currentBlockIndex + blocks.Count() % blocks.Count();
currentBlock = blocks[currentBlockIndex];
SetHighlight(currentBlock, true);
}
if (blocksGrid[winPosition] != null && blocksGrid[winPosition].ID == 0)
{
Debug.Log("Game finished!");
}
}
private void BuildPuzzle()
{
int size = 5;
tileGrid = RectGrid.Rectangle(size, size);
blocksGrid = (RectGrid)tileGrid.CloneStructure();
map = new RectMap(new Vector2(40, 40))
.AnchorCellMiddelCenter()
.WithWindow(ExampleUtils.ScreenRect)
.AlignMiddelCenter(tileGrid)
.To3DXY();
foreach (RectPoint point in tileGrid)
{
Cell cell = Instantiate(cellPrefab);
cell.transform.parent = uiRoot.transform;
cell.transform.localScale = Vector3.one;
cell.transform.localPosition = map[point];
cell.SetColor(ExampleUtils.ColorFromInt(40, 40, 40));
cell.HighlightOn = false;
cell.SetText("");
tileGrid[point] = cell;
blocksGrid[point] = null;
}
blocks = new List();
//First block
currentBlock = MakeBlock(0, BlockType.Horizontal, new RectPoint(2, 2));
SetHighlight(currentBlock, true);
blocks.Add(currentBlock);
//Other blocks
blocks.Add(MakeBlock(1, BlockType.Horizontal, new RectPoint(1, 1)));
blocks.Add(MakeBlock(2, BlockType.Vertical, new RectPoint(4, 2)));
blocks.Add(MakeBlock(3, BlockType.Horizontal, new RectPoint(3, 4)));
blocks.Add(MakeBlock(4, BlockType.Vertical, new RectPoint(2, 3)));
blocks.Add(MakeBlock(5, BlockType.Vertical, new RectPoint(4, 0)));
blocks.Add(MakeBlock(6, BlockType.Vertical, new RectPoint(3, 0)));
blocks.Add(MakeBlock(7, BlockType.Vertical, new RectPoint(0, 0)));
blocks.Add(MakeBlock(8, BlockType.Vertical, new RectPoint(0, 2)));
blocks.Add(MakeBlock(9, BlockType.Vertical, new RectPoint(1, 2)));
winPosition = new RectPoint(4, 2);
}
private bool CanOccupy(Block block, RectPoint gridPoint)
{
foreach (RectPoint tilePoint in block.TilePoints)
{
var absoluteTilePoint = gridPoint + tilePoint;
if (!tileGrid.Contains(absoluteTilePoint))
{
return false;
}
if ((blocksGrid[absoluteTilePoint] != null) && (blocksGrid[absoluteTilePoint] != block))
{
return false;
}
}
return true;
}
private Cell MakeTile()
{
Cell cell = Instantiate(cellPrefab);
cell.transform.parent = uiRoot.transform;
cell.transform.localScale = Vector3.one;
return cell;
}
private Block MakeBlock(int id, BlockType type, RectPoint initialPosition)
{
Block block = new Block(id);
if (type == BlockType.Horizontal)
{
block.AddTile(RectPoint.Zero, MakeTile());
block.AddTile(RectPoint.East, MakeTile());
}
else
{
block.AddTile(RectPoint.Zero, MakeTile());
block.AddTile(RectPoint.North, MakeTile());
}
if (CanOccupy(block, initialPosition))
{
foreach (Cell tile in block.TileObjects)
{
tile.SetColor(ExampleUtils.colors[id]);
tile.SetText("");
}
PlaceTile(block, initialPosition);
block.UpdateTilePositions(map);
}
else
{
Debug.LogError("Invalid placement. Making block empty");
foreach (Cell tile in block.TileObjects)
{
Destroy(tile.gameObject);
}
block.Clear();
}
return block;
}
private void PlaceTile(Block block, RectPoint gridPoint)
{
foreach (RectPoint tilePoint in block.TilePoints)
{
tileGrid[gridPoint + tilePoint].gameObject.active = false;
blocksGrid[gridPoint + tilePoint] = block;
}
block.CurrentPosition = gridPoint;
}
private void RemoveTile(Block block)
{
foreach (RectPoint tilePoint in block.TilePoints)
{
tileGrid[block.CurrentPosition + tilePoint].gameObject.active = true;
blocksGrid[block.CurrentPosition + tilePoint] = null;
}
}
private void SetHighlight(Block block, bool highlightOn)
{
foreach (Cell tile in block.TileObjects)
{
tile.HighlightOn = highlightOn;
}
}
}
| | | |