private static void AddWindowOnVerticalWall(FloorType[,] layout, VecInt2 wallStart, VecInt2 wallEnd) { int length = wallEnd.y - wallStart.y; if (length < 5) { } else if (length < 10) { AddOneWindow(layout, wallStart.x, wallStart.y + length / 2 - 1); AddOneWindow(layout, wallStart.x, wallStart.y + length / 2); AddOneWindow(layout, wallStart.x, wallStart.y + length / 2 + 1); } else if (length < 16) { AddOneWindow(layout, wallStart.x, wallStart.y + length / 3); AddOneWindow(layout, wallStart.x, wallStart.y + length / 3 + 1); AddOneWindow(layout, wallStart.x, wallStart.y + length * 2 / 3); AddOneWindow(layout, wallStart.x, wallStart.y + length * 2 / 3 + 1); } else { AddOneWindow(layout, wallStart.x, wallStart.y + length / 3 - 1); AddOneWindow(layout, wallStart.x, wallStart.y + length / 3); AddOneWindow(layout, wallStart.x, wallStart.y + length / 3 + 1); AddOneWindow(layout, wallStart.x, wallStart.y + length * 2 / 3 - 1); AddOneWindow(layout, wallStart.x, wallStart.y + length * 2 / 3); AddOneWindow(layout, wallStart.x, wallStart.y + length * 2 / 3 + 1); } }
private static void AddWindowOnHorizonWall(FloorType[,] layout, VecInt2 wallStart, VecInt2 wallEnd) { int length = wallEnd.x - wallStart.x; if (length < 6) { } else if (length < 12) { AddOneWindow(layout, wallStart.x + length / 2 - 1, wallStart.y); AddOneWindow(layout, wallStart.x + length / 2, wallStart.y); AddOneWindow(layout, wallStart.x + length / 2 + 1, wallStart.y); } else if (length < 18) { AddOneWindow(layout, wallStart.x + length / 3, wallStart.y); AddOneWindow(layout, wallStart.x + length / 3 + 1, wallStart.y); AddOneWindow(layout, wallStart.x + length * 2 / 3, wallStart.y); AddOneWindow(layout, wallStart.x + length * 2 / 3 + 1, wallStart.y); } else { AddOneWindow(layout, wallStart.x + length / 3 - 1, wallStart.y); AddOneWindow(layout, wallStart.x + length / 3, wallStart.y); AddOneWindow(layout, wallStart.x + length / 3 + 1, wallStart.y); AddOneWindow(layout, wallStart.x + length * 2 / 3 - 1, wallStart.y); AddOneWindow(layout, wallStart.x + length * 2 / 3, wallStart.y); AddOneWindow(layout, wallStart.x + length * 2 / 3 + 1, wallStart.y); } }
//----------------------------------------------------------------------------------- protected override void ProcessOneStep() { if (figure != null) { DrawCurrentFigure(false); } else { //1 for x cause it would be subtracted next lines VecInt2 vNextPos = new VecInt2(m_nSizeX / 2, m_nSizeY); //Check round end if (SetNewFigure(m_nextFigure, vNextPos, m_nextFigure.rot)) { CreateNextFigure(); } else { GameEnd(); return; } } VecInt2 vNewPos = new VecInt2(figure.pos.x, figure.pos.y - 1); bool bStillGo = CheckFigurePos(vNewPos); if (bStillGo) { figure.pos = vNewPos; if (m_delChangePos != null) { m_delChangePos(); } } //Draw anyway DrawCurrentFigure(true); //The figure is in place if (!bStillGo) { if (m_delFigurePlaced != null) { m_delFigurePlaced(); } SetNewFigure(null, null, 0); if (FindFullLines()) { CollapseLines(); } } }
//----------------------------------------------------------------------------------- protected override void ProcessOneStep() { DrawCurrentFigure(false); if (figure != null) { VecInt2 vNewPos = new VecInt2(figure.pos.x, figure.pos.y - 1); if (CheckFigurePos(vNewPos)) { figure.pos = vNewPos; } //Wait for end step from remote client } //Draw anyway DrawCurrentFigure(true); }
//----------------------------------------------------------------------------------- protected bool SetNewFigure(Figure figure, VecInt2 vNewPos, int nRot) { m_curFigure = figure; if (m_curFigure != null && CheckFigurePos(vNewPos)) { m_curFigure.pos = vNewPos; m_curFigure.rot = nRot; if (m_delNewFigure != null) { m_delNewFigure(); } return(true); } return(false); }
//----------------------------------------------------------------------------------- //Is given pos not taken //----------------------------------------------------------------------------------- protected bool CheckFigurePos(VecInt2 vCurrPos) { if (m_curFigure == null) { return(false); } VecInt2 vStartPos = vCurrPos - m_curFigure.GetCenterPoint(); var mtx = m_curFigure.matrix; for (int x = 0; x < mtx.GetLength(0); x++) { for (int y = 0; y < mtx.GetLength(1); y++) { int nActX = x + vStartPos.x; if (nActX < 0 || nActX >= m_nSizeX) { return(false); } int nActY = y + vStartPos.y; //No limit from up if (nActY < 0 /* || nActY >= m_nSizeY*/) { return(false); } if (nActY >= m_nSizeY) { continue; } //No element there if (mtx[x, y] == 0) { continue; } //Already taken if (m_arField[nActX, nActY] != null) { return(false); } } } return(true); }
//----------------------------------------------------------------------------------- // Update is called once per frame //----------------------------------------------------------------------------------- protected override void UpdateImpl() { Logic.GlassLocal glass = (Logic.GlassLocal)m_glass; //TODO: Move to Callback form glass if (glass == null || m_block == null) { return; } RectTransform tf = GetComponent <RectTransform>(); const int PREVIEW_SIZE = 4; float fSizeX = tf.rect.width / PREVIEW_SIZE; float fSizeY = tf.rect.height / PREVIEW_SIZE; Logic.Figure fig = glass.nextFigure; var mtx = fig.matrix; VecInt2 vCenter = fig.GetCenterPoint(); for (int x = 0; x < PREVIEW_SIZE; x++) { if (x > mtx.GetLength(0) - 1) { continue; } for (int y = 0; y < PREVIEW_SIZE; y++) { if (y > mtx.GetLength(1) - 1) { continue; } int nVal = mtx[x, y]; if (nVal != 0) { GameObject block = GetNextBlock(); //Vector3 vPos = new Vector3(fSizeX*(x - fCenterX), fSizeY*(y - fCenterY), 0.0f); RectTransform btf = block.GetComponent <RectTransform>(); btf.anchoredPosition = new Vector3(fSizeX * (x - vCenter.x), fSizeY * (y - vCenter.y)); btf.SetSizeWithCurrentAnchors(RectTransform.Axis.Horizontal, fSizeX); btf.SetSizeWithCurrentAnchors(RectTransform.Axis.Vertical, fSizeY); } } } }
//----------------------------------------------------------------------------------- protected void DrawCurrentFigure(bool bDraw) { if (m_curFigure == null) { return; } VecInt2 vStartPos = m_curFigure.pos - m_curFigure.GetCenterPoint(); var mtx = m_curFigure.matrix; for (int x = 0; x < mtx.GetLength(0); x++) { for (int y = 0; y < mtx.GetLength(1); y++) { int nActX = x + vStartPos.x; if (nActX < 0 || nActX >= m_nSizeX) { continue; } int nActY = y + vStartPos.y; if (nActY < 0 || nActY >= m_nSizeY) { continue; } if (mtx[x, y] == 0) { continue; } if (bDraw) { m_arField[nActX, nActY] = new Block(); } else { m_arField[nActX, nActY] = null; } } } }
//----------------------------------------------------------------------------------- //Input //----------------------------------------------------------------------------------- public void OnInputEvent(int nKey, bool bDown) { if (figure == null) { return; } VecInt2 vOldPos = new VecInt2(figure.pos); int nOldRot = figure != null ? figure.rot : 0; ProcessInput(nKey, bDown); int nRot = figure != null ? figure.rot : 0; if (vOldPos != figure.pos || nOldRot != nRot) { if (m_delChangePos != null) { m_delChangePos(); } } }
public static RectInt GetRange(VecInt2 doorPos, int w, int h, Direction dir) { RectInt range; if (dir == Direction.Up) { range = new RectInt(doorPos.x - w / 2, doorPos.y, w, h); } else if (dir == Direction.Down) { range = new RectInt(doorPos.x - w / 2, doorPos.y - h + 1, w, h); } else if (dir == Direction.Left) { range = new RectInt(doorPos.x - w + 1, doorPos.y - h / 2, w, h); } else //Right { range = new RectInt(doorPos.x, doorPos.y - h / 2, w, h); } return(range); }
public Tile(int x, int y) { m_pos = new VecInt2 (x, y); }
//----------------------------------------------------------------------------------- private InputProvider.EInputAction EvaluateNextStep() { VecInt2 vNewPos = FindBestPos(); return(InputProvider.EInputAction.NONE); }
public Room(VecInt2 doorPos, FloorType type, int targetSize) { this.doorPos = doorPos; this.type = type; this.targetSize = targetSize; }
public static Room CreateMinRoom(ref FloorType[,] blocks, BlueprintNode blueprint, VecInt2 doorPos, Direction doorDir) { Room room = new Room(doorPos, blueprint.type, FakeRandom.Range(blueprint.sizeMin, blueprint.sizeMax)); room.range = GetRange(doorPos, blueprint.edgeLenghtMin, blueprint.edgeLenghtMin, doorDir); room.dir = doorDir; Array2DTool.SetRange(blocks, room.range, blueprint.type); Array2DTool.SetOne(blocks, room.doorPos.x, room.doorPos.y, doorType[(int)room.dir]); return(room); }
public static List <Room> CreateChildren(ref FloorType[,] blocks, Room room, BlueprintNode blueprint) { List <Room> children = new List <Room>(); for (int i = 0; i < blueprint.children.Count; i++) { BlueprintNode childBlueprint = blueprint.children[i]; VecInt2 childDoorPos = new VecInt2(0, 0); Direction childDoorDir = Direction.Left; bool bValid = false; Direction[] dirs = GetExtendDirections(room.dir); //得到可以产生门的方向 dirs = RandomSort(dirs, FakeRandom.Range(0, 10000)); //打乱顺序 foreach (Direction d in dirs) { for (int t = 0; t < 5; t++) { childDoorPos = GetRandomChildDoorPos(room.range, d);//在随机位置生生成一个门 childDoorDir = d; RectInt childMinRange = GetRange(childDoorPos, childBlueprint.edgeLenghtMin, childBlueprint.edgeLenghtMin, d); if (Array2DTool.RangeIsAll(blocks, childMinRange, FloorType.Out)) //如果是空地 { bValid = true; //则找到了一个有效位置 break; } } if (bValid) { break; } } if (bValid) //如果找到了一个有效的位置 { Room childRoom = CreateMinRoom(ref blocks, childBlueprint, childDoorPos, childDoorDir); //在此位置生成一个最小房间 if (childRoom != null) { childRoom.blueprint = childBlueprint; children.Add(childRoom); } } } while (true) { bool bExtendOne = false; for (int i = 0; i < children.Count; i++) { if (children[i].GetCurrentSize() < children[i].targetSize) //如果房间大小还没到期望值 { bool bExtendOk = Extend(ref blocks, children[i]); //则往随机方向扩大一格 bExtendOne |= bExtendOk; } } if (!bExtendOne) //如果没有任何房间被扩大过,则退出循环 { break; } } //给扩展过的子房间产生下一级房间 for (int i = 0; i < children.Count; i++) { children[i].children = CreateChildren(ref blocks, children[i], children[i].blueprint); } return(children); }
// VecInt2 m_size; //Tile[] m_tiles; public Platform(Tile startTile) { m_right = startTile.m_pos.Clone (); m_left = startTile.m_pos.Clone (); m_pos = startTile.m_pos.Clone (); }
public static void AddWindow(FloorType[,] layout) { int w = layout.GetLength(0); int h = layout.GetLength(1); for (int j = 1; j < h - 1; j++) { bool bWaitWallStart = true; bool bWaitWallEnd = false; VecInt2 wallStart = new VecInt2(); VecInt2 wallEnd = new VecInt2(); for (int i = 1; i < w - 1; i++) { if (bWaitWallStart) { if (layout[i, j] == FloorType.Wall) { bWaitWallStart = false; bWaitWallEnd = true; wallStart = new VecInt2(i, j); continue; } } if (bWaitWallEnd) { if (layout[i, j] != FloorType.Wall || layout[i, j + 1] == FloorType.Wall || layout[i, j - 1] == FloorType.Wall) { bWaitWallEnd = false; bWaitWallStart = true; wallEnd = new VecInt2(i, j); AddWindowOnHorizonWall(layout, wallStart, wallEnd); continue; } } } } for (int i = 1; i < w - 1; i++) { bool bWaitWallStart = true; bool bWaitWallEnd = false; VecInt2 wallStart = new VecInt2(); VecInt2 wallEnd = new VecInt2(); for (int j = 1; j < h - 1; j++) { if (bWaitWallStart) { if (layout[i, j] == FloorType.Wall) { bWaitWallStart = false; bWaitWallEnd = true; wallStart = new VecInt2(i, j); continue; } } if (bWaitWallEnd) { if (layout[i, j] != FloorType.Wall || layout[i + 1, j] == FloorType.Wall || layout[i - 1, j] == FloorType.Wall) { bWaitWallEnd = false; bWaitWallStart = true; wallEnd = new VecInt2(i, j); AddWindowOnVerticalWall(layout, wallStart, wallEnd); continue; } } } } }
public static int[,] GetDistanceToWall(FloorType[,] layout) { int w = layout.GetLength(0); int l = layout.GetLength(1); int[,] rlt = new int[w, l]; const int Max = 99; int curValue = Max; List <VecInt2> maxCells = new List <VecInt2>(); for (int i = 0; i < w; i++) { for (int j = 0; j < l; j++) { //rlt[i, j] = layout[i, j] == FloorType.Wall ? Max : 0; if (layout[i, j] == FloorType.Wall) { rlt[i, j] = curValue; maxCells.Add(new VecInt2(i, j)); } } } while (maxCells.Count > 0) { List <VecInt2> newCells = new List <VecInt2>(); for (int c = 0; c < maxCells.Count; c++) { VecInt2 cell = maxCells[c]; int value = rlt[cell.x, cell.y]; if (cell.x > 0 && rlt[cell.x - 1, cell.y] < value - 1) { rlt[cell.x - 1, cell.y] = value - 1; newCells.Add(new VecInt2(cell.x - 1, cell.y)); } if (cell.x < w - 1 && rlt[cell.x + 1, cell.y] < value - 1) { rlt[cell.x + 1, cell.y] = value - 1; newCells.Add(new VecInt2(cell.x + 1, cell.y)); } if (cell.y > 0 && rlt[cell.x, cell.y - 1] < value - 1) { rlt[cell.x, cell.y - 1] = value - 1; newCells.Add(new VecInt2(cell.x, cell.y - 1)); } if (cell.y < l - 1 && rlt[cell.x, cell.y + 1] < value - 1) { rlt[cell.x, cell.y + 1] = value - 1; newCells.Add(new VecInt2(cell.x, cell.y + 1)); } } maxCells = newCells; } for (int i = 0; i < w; i++) { for (int j = 0; j < l; j++) { rlt[i, j] = Max - rlt[i, j]; } } return(rlt); }
public void Set(VecInt2 pos) { Set (pos.x, pos.y); }
//----------------------------------------------------------------------------------- // Functions //----------------------------------------------------------------------------------- public void ProcessInput(int nKey, bool bDown) { if (m_bPaused) { return; } if (m_curFigure == null) { return; } DrawCurrentFigure(false); if (nKey == (int)InputProvider.EInputAction.ROTATE && bDown) { m_curFigure.Rotate(1); if (!CheckFigurePos(m_curFigure.pos)) { //Try move left-right to fit it int nSizeX = m_curFigure.matrix.GetLength(0); int nOffsetX = -nSizeX / 2; bool bOk = false; for (int x = 0; x < nSizeX; x++) { VecInt2 vNewPos = new VecInt2(m_curFigure.pos.x + x + nOffsetX, m_curFigure.pos.y); if (CheckFigurePos(vNewPos)) { m_curFigure.pos = vNewPos; bOk = true; break; } } if (!bOk) { m_curFigure.Rotate(-1); } } } else if (nKey == (int)InputProvider.EInputAction.LEFT && bDown) { VecInt2 vNewPos = new VecInt2(m_curFigure.pos.x - 1, m_curFigure.pos.y); if (CheckFigurePos(vNewPos)) { m_curFigure.pos = vNewPos; } } else if (nKey == (int)InputProvider.EInputAction.RIGHT && bDown) { VecInt2 vNewPos = new VecInt2(m_curFigure.pos.x + 1, m_curFigure.pos.y); if (CheckFigurePos(vNewPos)) { m_curFigure.pos = vNewPos; } } else if (nKey == (int)InputProvider.EInputAction.DOWN) { if (bDown) { ProcessOneStep(); m_stepTimer.Reset(); } //UpdateTimeInterval(); } DrawCurrentFigure(true); }