public List <IVector2> GetNeighborCoordsOf(int _x, int _y, bool _useDiag = false) { var neighbors = new List <IVector2>(); for (var x = _x - 1; x <= _x + 1; ++x) { for (var y = _y - 1; y <= _y + 1; ++y) { var p = new IVector2(x, y); if (CoordInRange(new IVector2(p.x, p.y))) { if (!p.Equals(new IVector2(_x, _y))) { if (!_useDiag) { if (Math.Abs(_x - x) + Math.Abs(_y - y) == 1) { neighbors.Add(p); } } else { neighbors.Add(p); } } } } } return(neighbors); }
public static G2Dir VecToDir(IVector2 _from, IVector2 _to) { IVector2 result = _from - _to; if (result.Equals(IVector2.XnYp)) { return(G2Dir.UL); } if (result.Equals(IVector2.Yp)) { return(G2Dir.U); } if (result.Equals(IVector2.XpYp)) { return(G2Dir.UR); } if (result.Equals(IVector2.Xp)) { return(G2Dir.R); } if (result.Equals(IVector2.XpYn)) { return(G2Dir.DR); } if (result.Equals(IVector2.Yn)) { return(G2Dir.D); } if (result.Equals(IVector2.XnYn)) { return(G2Dir.DL); } if (result.Equals(IVector2.Xn)) { return(G2Dir.L); } throw new ArgumentOutOfRangeException("Vector " + _from + " is not a neighbor of Vector " + _to); }
void UpdateTiles() { // determine offset point on tilemap where to retreive the tiles IVector2 tilemapOffset = new IVector2(Mathf.FloorToInt(pHor),Mathf.FloorToInt(pVer)); // determine scolling position tilesprite to get a smooth scrolling effect Vector2 scrollPosition = new Vector2( -((pHor - tilemapOffset.x) * (float)tilesSprite.tileSize.x), (pVer - tilemapOffset.y) * (float)tilesSprite.tileSize.y); // check if offset has changed and we need to refill the sprite if (!tilemapOffset.Equals(lastOffset)) { tilesSprite.FillFromTileMap(tilemap, tilemapOffset, new Rect(1,0,11,11)); lastOffset = tilemapOffset; } // set position of sprite to achieve a smooth scrolling effect tilesSprite.position = scrollPosition; }
// ------------------------------------------------------------------------------------------------------------------------------ // public methods // ------------------------------------------------------------------------------------------------------------------------------ /// <summary> /// Scroll the tiles with a certain delta (d) /// </summary> public void Scroll(IVector2 d, bool keepTiles) { if (d.Equals(IVector2.zero)) return; if (mesh == null) return; Color[] colors = mesh.colors; if (d.y!=0) { // scrolling up or down int dy = Mathf.Abs(d.y); int[] tmpTiles = new int[dy * tileMatrix.x]; object[] tmpObjects = new object[dy * tileMatrix.x]; float[] tmpAlpha = new float[dy * tileMatrix.x]; Color[] tmpColors = new Color[dy * tileMatrix.x * 4]; int idx = 0; int cidx = 0; int yv,yt,yd; if (keepTiles) { // scroll up yv = tileMatrix.y-1; yt = tileMatrix.y-dy; yd = -1; if (d.y<0) { // scroll down yv = 0; yt = dy; yd = 1; } for (int y=yv; (d.y<0)?(y<yt):(y>=yt); y+=yd) for (int x=0; x<tileMatrix.x; x++) { tmpTiles[idx] = tiles[x][y]; tmpAlpha[idx] = alphas[x][y]; tmpObjects[idx++] = objects[x][y]; int vidx = ((x * tileMatrix.y) + y) * 4; tmpColors[cidx++] = colors[vidx]; tmpColors[cidx++] = colors[vidx+1]; tmpColors[cidx++] = colors[vidx+2]; tmpColors[cidx++] = colors[vidx+3]; } } // scroll up yv = tileMatrix.y-1-dy; yt = 0; yd = -1; if (d.y<0) { // scroll down yv = dy; yt = tileMatrix.y; yd = 1; } for (int y=yv; (d.y<0)?(y<yt):(y>=yt); y+=yd) for (int x=0; x<tileMatrix.x; x++) { tiles[x][y+d.y] = tiles[x][y]; objects[x][y+d.y] = objects[x][y]; alphas[x][y+d.y] = alphas[x][y]; int vidxt = ((x * tileMatrix.y) + y + d.y) * 4; int vidxf = ((x * tileMatrix.y) + y ) * 4; colors[vidxt] = colors[vidxf]; colors[vidxt+1] = colors[vidxf+1]; colors[vidxt+2] = colors[vidxf+2]; colors[vidxt+3] = colors[vidxf+3]; } if (keepTiles) { idx = 0; cidx = 0; // scroll up yv = dy-1; yt = 0; yd = -1; if (d.y<0) { // scroll down yv = tileMatrix.y-dy; yt = tileMatrix.y; yd = 1; } for (int y=yv; (d.y<0)?(y<yt):(y>=yt); y+=yd) for (int x=0; x<tileMatrix.x; x++) { tiles[x][y] = tmpTiles[idx]; alphas[x][y] = tmpAlpha[idx]; objects[x][y] = tmpObjects[idx++]; int vidx = ((x * tileMatrix.y) + y) * 4; colors[vidx] = tmpColors[cidx++]; colors[vidx+1] = tmpColors[cidx++]; colors[vidx+2] = tmpColors[cidx++]; colors[vidx+3] = tmpColors[cidx++]; } } else { if (d.y<0) Clear(TilesBlock(new Rect(1,tileMatrix.y-(dy-1),tileMatrix.x,dy))); else Clear(TilesBlock(new Rect(1,1,tileMatrix.x,dy))); } } if (d.x!=0) { // scrolling up or down int dx = Mathf.Abs(d.x); int[] tmpTiles = new int[dx * tileMatrix.y]; object[] tmpObjects = new object[dx * tileMatrix.y]; float[] tmpAlpha = new float[dx * tileMatrix.y]; Color[] tmpColors = new Color[dx * tileMatrix.y * 4]; int idx = 0; int cidx = 0; int xv,xt,xd; if (keepTiles) { // scroll right xv = tileMatrix.x-1; xt = tileMatrix.x-dx; xd = -1; if (d.x<0) { // scroll down xv = 0; xt = dx; xd = 1; } for (int y=0; y<tileMatrix.y; y++) for (int x=xv; (d.x<0)?(x<xt):(x>=xt); x+=xd) { tmpTiles[idx] = tiles[x][y]; tmpAlpha[idx] = alphas[x][y]; tmpObjects[idx++] = objects[x][y]; int vidx = ((x * tileMatrix.y) + y) * 4; tmpColors[cidx++] = colors[vidx]; tmpColors[cidx++] = colors[vidx+1]; tmpColors[cidx++] = colors[vidx+2]; tmpColors[cidx++] = colors[vidx+3]; } } // scroll up xv = tileMatrix.x-1-dx; xt = 0; xd = -1; if (d.x<0) { // scroll down xv = dx; xt = tileMatrix.x; xd = 1; } for (int y=0; y<tileMatrix.y; y++) for (int x=xv; (d.x<0)?(x<xt):(x>=xt); x+=xd) { tiles[x+d.x][y] = tiles[x][y]; alphas[x+d.x][y] = alphas[x][y]; objects[x+d.x][y] = objects[x][y]; int vidxt = (((x + d.x) * tileMatrix.y) + y) * 4; int vidxf = ((x * tileMatrix.y) + y ) * 4; colors[vidxt] = colors[vidxf]; colors[vidxt+1] = colors[vidxf+1]; colors[vidxt+2] = colors[vidxf+2]; colors[vidxt+3] = colors[vidxf+3]; } if (keepTiles) { idx = 0; cidx = 0; // scroll up xv = dx-1; xt = 0; xd = -1; if (d.x<0) { // scroll down xv = tileMatrix.x-dx; xt = tileMatrix.x; xd = 1; } for (int y=0; y<tileMatrix.y; y++) for (int x=xv; (d.x<0)?(x<xt):(x>=xt); x+=xd) { tiles[x][y] = tmpTiles[idx]; alphas[x][y] = tmpAlpha[idx]; objects[x][y] = tmpObjects[idx++]; int vidx = ((x * tileMatrix.y) + y) * 4; colors[vidx] = tmpColors[cidx++]; colors[vidx+1] = tmpColors[cidx++]; colors[vidx+2] = tmpColors[cidx++]; colors[vidx+3] = tmpColors[cidx++]; } } else { if (d.x<0) Clear(TilesBlock(new Rect(tileMatrix.x-(dx-1),1,dx,tileMatrix.y))); else Clear(TilesBlock(new Rect(1,1,dx,tileMatrix.y))); } } mesh.colors = colors; Repaint(); }
/// <summary> /// 處理移動(檢查都通過時的處理) /// </summary> /// <param name="start">玩家決定的移動起點</para> /// <param name="end">玩家決定的移動終點</param> /// <param name="realEnd">實際的移動終點</param> /// <param name="infectPositions">感染的座標範圍</param> public MoveType Move(IVector2 start, IVector2 end, out IVector2 realEnd, out List <IVector2> infectPositions) { MoveType moveType = MoveType.Move; realEnd = end.Clone(); infectPositions = new List <IVector2>(); Creature creature = map.GetCreature(start); // 取得要移動的生物 if (creature == Creature.None) { return(MoveType.None); } if (creature == Creature.People) { map.SetCreature(realEnd, creature); // 由於是合法移動,不是差一就二 if (Mathf.Abs(realEnd.x - start.x) == 1 || Mathf.Abs(realEnd.y - start.y) == 1) { moveType = MoveType.Clone; } else { map.SetCreature(start, Creature.None); // 跳耀,所以要刪除原本的 } //感染 foreach (IVector2 neiDir in neighborDir) { IVector2 neighbor = new IVector2(realEnd.x + neiDir.x, realEnd.y + neiDir.y); if (!neighbor.Equals(start)) // 起點不受影響 { bool infectSuccess = map.Infect(neighbor, creature); if (infectSuccess) { infectPositions.Add(neighbor); } } } } else if (creature == Creature.Scarab) { IVector2 transportPos; bool isTransPort = map.CanTransport(creature, end, out transportPos); if (isTransPort) // 瞬間移動,原本的必定砍掉 { map.SetCreature(start, Creature.None); realEnd = transportPos.Clone(); } else { // 由於是合法移動,不是差一就二 if (Mathf.Abs(realEnd.x - start.x) == 1 || Mathf.Abs(realEnd.y - start.y) == 1) { moveType = MoveType.Clone; } else { map.SetCreature(start, Creature.None); // 跳耀,所以要刪除原本的 } } map.SetCreature(realEnd, creature); //感染 foreach (IVector2 neiDir in neighborDir) { IVector2 neighbor = new IVector2(realEnd.x + neiDir.x, realEnd.y + neiDir.y); if (!neighbor.Equals(start)) // 起點不受影響 { bool infectSuccess = map.Infect(neighbor, creature); if (infectSuccess) { infectPositions.Add(neighbor); } } } } // TODO: 優化能夠移動到的地點相關的處理 map.RecheckAllCanMove(); return(moveType); }