public static List <Vec2Int> Diagonals(this Vec2Int p, int size) { var diagonals = new List <Vec2Int>(); if (p.X - 1 >= 0 && p.Y - 1 >= 0) { diagonals.Add(new Vec2Int(p.X - 1, p.Y - 1)); } if (p.X + size < 80 && p.Y - 1 >= 0) { diagonals.Add(new Vec2Int(p.X + size, p.Y - 1)); } if (p.X + size < 80 && p.Y + size < 80) { diagonals.Add(new Vec2Int(p.X + size, p.Y + size)); } if (p.X - 1 >= 0 && p.Y + size < 80) { diagonals.Add(new Vec2Int(p.X - 1, p.Y + size)); } return(diagonals); }
public static bool Passable(Vec2Int p, int size) { for (int x = 0; x < size; x++) { if (p.X + x >= 80) { return(false); } for (int y = 0; y < size; y++) { if (p.Y + y >= 80) { return(false); } if (Map[p.X + x, p.Y + y].Entity != null) { return(false); } } } return(true); }
public static List <Vec2Int> Neighbors(this Vec2Int p) { var neighbors = new List <Vec2Int>(); // up if (p.Y - 1 >= 0) { neighbors.Add(new Vec2Int(p.X, p.Y - 1)); } // right if (p.X - 1 >= 0) { neighbors.Add(new Vec2Int(p.X - 1, p.Y)); } // down if (p.Y + 1 < 80) { neighbors.Add(new Vec2Int(p.X, p.Y + 1)); } // left if (p.X + 1 < 80) { neighbors.Add(new Vec2Int(p.X + 1, p.Y)); } return(neighbors); }
private double GetDistance(Vec2Int one, Vec2Int two) { var distX = two.X - one.X; var distY = two.Y - one.Y; return(Math.Sqrt(distX * distX + distY * distY)); }
public Entity GetNearestEntity(Vec2Int sourcePosition, PlayerType playerType) { IEnumerable <Entity> targetCollection; switch (playerType) { case PlayerType.My: targetCollection = MyEntities; break; case PlayerType.Enemy: targetCollection = EnemyEntities; break; default: throw new ArgumentOutOfRangeException(nameof(playerType), playerType, null); } double distanceBetween = 1000; var nearestEntity = new Entity(); foreach (var ett in targetCollection) // todo to LINQ { var dst = GetDistance(ett.Position, sourcePosition); if (dst < distanceBetween) { distanceBetween = dst; nearestEntity = ett; } } return(nearestEntity); }
public void ShowTempObject(UIManager.UIObjectType objectTypeToDisplay, Vector3 position) { //If no hologram, grab one if (m_objectHologram == null) { m_objectHologram = CacheManager.Singleton.RequestInteriorDoor(); m_objectHologram.gameObject.SetActive(true); m_objectHologram.transform.parent = null; m_objectHologram.SetMaterial(PrefabAssets.Singleton.doorHologramMat); switch (objectTypeToDisplay) { case UIManager.UIObjectType.Door: m_objectHologram.tileType = GroundManager.GroundTileType.Door; break; } } m_hologramObjectLocationValid = false; Vec2Int tilePos = GroundManager.Singleton.ConvertWorldPositionToTile(position); m_objectHologram.transform.position = new Vector3(tilePos.x + m_objectHologram.defaultOffset.x, 0, tilePos.y + m_objectHologram.defaultOffset.z); Color holoColor = PrefabAssets.Singleton.hologramColor; GroundManager.GroundTileType curTile = m_associatedGroundData.GetTileType(tilePos); if (m_objectHologram.tileType == GroundManager.GroundTileType.Door) { if (curTile == GroundManager.GroundTileType.Wall) { int index = m_associatedGroundData.ConvertVec2IntToInt(tilePos); BaseGroundObject baseObj = m_groundTilesGOs[index]; if (baseObj is WallObject) { GroundManager.WallType wallType = (baseObj as WallObject).WallType; //Doors can only go on straight walls if (wallType == GroundManager.WallType.Straight) { m_objectHologram.transform.rotation = baseObj.transform.rotation; m_hologramObjectLocationValid = true; } else { holoColor = PrefabAssets.Singleton.hologramColorError; } } } else { holoColor = PrefabAssets.Singleton.hologramColorError; } } m_objectHologram.SetMaterialColor(holoColor); }
private Vec2Int GetRndPositionAround(Entity building) // recursively delete { var buildingSize = View.EntityProperties.Single(ep => ep.Key == building.EntityType).Value.Size; List <int[]> targetCollection; if (buildingSize == 5) { targetCollection = positionsToBuildAround5; } else if (buildingSize == 3) { targetCollection = positionsToBuildAround3; } else { targetCollection = positionsToBuildAround2; } var rndPositionToBuild = targetCollection.ElementAt(new Random().Next(targetCollection.Count)); var positionToBuild = new Vec2Int(building.Position.X + rndPositionToBuild.ElementAt(0), building.Position.Y + rndPositionToBuild.ElementAt(1)); // if (recursivelyTillFind) // { // return Around.MyUnits.Any(my => my.Position.X == positionToBuild.X && // my.Position.Y == positionToBuild.Y) // ? GetRndPositionAround(building) // : positionToBuild; // } return(positionToBuild); }
public void RangeTest() { Vec2Int p = new Vec2Int(1, 1); var radius = p.Range(1); Assert.True(radius.Count == 4); }
private static void SetBuildUnitAction(Entity entity, Vec2Int approxTarget, EntityType buildUnit, int unitCost, Dictionary <int, EntityAction> entityActions) { Vec2Int?target = null; int minDistance = int.MaxValue; var neighbors = entity.Position.Neighbors(5); foreach (var position in neighbors) { if (ScoreMap.Passable(position)) { int distance = position.Distance(approxTarget); if (distance < minDistance) { target = position; minDistance = distance; } } } if (target != null) { var buildAction = new BuildAction(buildUnit, target.Value); entityActions.Add(entity.Id, new EntityAction(null, buildAction, null, null)); ScoreMap.Build(target.Value, 1); ScoreMap.MyResource -= unitCost; } }
public static Vec2Int ReadFrom(System.IO.BinaryReader reader) { var result = new Vec2Int(); result.X = reader.ReadInt32(); result.Y = reader.ReadInt32(); return(result); }
public static Vec2Int ReadFrom(System.IO.BinaryReader reader) { int x = reader.ReadInt32(); int y = reader.ReadInt32(); var result = new Vec2Int(x, y); return(result); }
public virtual void AssignToPosition(Vec2Int position, float rot, bool asHologram) { this.transform.parent = this.transform; this.transform.position = new Vector3(position.x + defaultOffset.x, defaultOffset.y, position.y + defaultOffset.z); this.gameObject.SetActive(true); this.transform.rotation = Quaternion.Euler(0f, rot, 0f); this.SetTilePos(position); }
private static Vec2Int GetPositionForUnit(Entity builderBase, PlayerView playerView) { Vec2Int basePosition = builderBase.Position; int size = builderBase.Properties.Size; List <Vec2Int> respawnPlaces = new List <Vec2Int>(size * 2); for (int x = 0; x < size; x++) { Vec2Int posX = basePosition; Vec2Int posY = basePosition; posX.X += size; posX.Y += (size - 1 - x); posY.Y += size; posY.X += (size - 1 - x); respawnPlaces.Add(posX); respawnPlaces.Add(posY); } foreach (Entity entity in playerView.Entities) { int entitySize = entity.Properties.Size; Vec2Int[] entityPlace = new Vec2Int[entitySize * entitySize]; int index = 0; for (int x = 0; x < entitySize; x++) { for (int y = 0; y < entitySize; y++) { Vec2Int entityPos = entity.Position; entityPos.X += x; entityPos.Y += y; entityPlace[index++] = entityPos; } } foreach (var pl in entityPlace) { index = respawnPlaces.IndexOf(pl); if (index >= 0) { respawnPlaces.RemoveAt(index); } } } if (respawnPlaces.Any()) { return(respawnPlaces.First()); } return(new Vec2Int(basePosition.X + size, basePosition.Y - 1)); }
public static void SetAttack(Entity entity, int attackRange, int size, Dictionary <int, EntityAction> entityActions) { if (entityActions.ContainsKey(entity.Id)) { return; } if (entity.EntityType == EntityType.RangedUnit && ScoreMap.Get(entity.Position).MeleeDamage > 0) { return; } List <Vec2Int> range = new List <Vec2Int>(); if (size > 1) { for (int y = entity.Position.Y; y < entity.Position.Y + size; y++) { for (int x = entity.Position.X; x < entity.Position.X + size; x++) { var position = new Vec2Int(x, y); range.AddRange(position.Range(attackRange)); } } range = range.Distinct().ToList(); } else { range = entity.Position.Range(attackRange); } var enemiesUnderAttack = new HashSet <Entity>(); foreach (var position in range) { var cell = ScoreMap.Get(position); if (cell.Entity != null && cell.Entity?.EntityType != EntityType.Resource && cell.Entity?.PlayerId != ScoreMap.MyId && !enemiesUnderAttack.Contains(cell.Entity.Value)) { enemiesUnderAttack.Add(cell.Entity.Value); } } SetAttack(entity, EntityType.RangedUnit, 1, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.BuilderUnit, 1, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.MeleeUnit, 1, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.Turret, 2, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.RangedBase, 5, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.MeleeBase, 5, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.BuilderBase, 5, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.House, 3, enemiesUnderAttack, entityActions); SetAttack(entity, EntityType.Wall, 1, enemiesUnderAttack, entityActions); }
public static MoveAction ReadFrom(System.IO.BinaryReader reader) { Vec2Int target = Model.Vec2Int.ReadFrom(reader); bool findClosestPosition = reader.ReadBoolean(); bool breakThrough = reader.ReadBoolean(); var result = new MoveAction(target, findClosestPosition, breakThrough); return(result); }
public static void DrawLine(Vec2Int p1, Vec2Int p2, Color color, DebugInterface debugInterface) { var vertex1 = new ColoredVertex(new Vec2Float(p1.X + 0.5f, p1.Y + 0.5f), new Vec2Float(0, 0), color); var vertex2 = new ColoredVertex(new Vec2Float(p2.X + 0.5f, p2.Y + 0.5f), new Vec2Float(0, 0), color); var debugData = new DebugData.Primitives(new[] { vertex1, vertex2 }, PrimitiveType.Lines); var debugCommand = new DebugCommand.Add(debugData); debugInterface.Send(debugCommand); }
public static void Build(Vec2Int p, int size) { for (int x = 0; x < size; x++) { for (int y = 0; y < size; y++) { Map[p.X + x, p.Y + y].Entity = new Entity(); } } }
public static BuildAction ReadFrom(System.IO.BinaryReader reader) { Model.EntityType entityType; switch (reader.ReadInt32()) { case 0: entityType = Model.EntityType.Wall; break; case 1: entityType = Model.EntityType.House; break; case 2: entityType = Model.EntityType.BuilderBase; break; case 3: entityType = Model.EntityType.BuilderUnit; break; case 4: entityType = Model.EntityType.MeleeBase; break; case 5: entityType = Model.EntityType.MeleeUnit; break; case 6: entityType = Model.EntityType.RangedBase; break; case 7: entityType = Model.EntityType.RangedUnit; break; case 8: entityType = Model.EntityType.Resource; break; case 9: entityType = Model.EntityType.Turret; break; default: throw new System.Exception("Unexpected tag value"); } Vec2Int position = Model.Vec2Int.ReadFrom(reader); var result = new BuildAction(entityType, position); return(result); }
// Neighbors with left down corner public static List <Vec2Int> BuildPositions(this Vec2Int p, int size) { var buildPositions = new List <Vec2Int>(); // up if (p.Y - size >= 0) { for (int i = 0; i < size; i++) { if (p.X - i >= 0) { buildPositions.Add(new Vec2Int(p.X - i, p.Y - size)); } } } // right if (p.X - size >= 0) { for (int i = 0; i < size; i++) { if (p.Y - i >= 0) { buildPositions.Add(new Vec2Int(p.X - size, p.Y - i)); } } } // down if (p.Y + 1 < 80) { for (int i = 0; i < size; i++) { if (p.X - i >= 0) { buildPositions.Add(new Vec2Int(p.X - i, p.Y + 1)); } } } // left if (p.X + 1 < 80) { for (int i = 0; i < size; i++) { if (p.Y - i >= 0) { buildPositions.Add(new Vec2Int(p.X + 1, p.Y - i)); } } } return(buildPositions); }
/// <summary> /// 是否还须扩展,满足2的n次方不需要 /// </summary> /// <param name="path"></param> /// <returns></returns> public static bool GetWrapEnable(string path) { Texture2D texture = AssetDatabase.LoadAssetAtPath <Texture2D>(path); if (texture != null) { Vec2Int wrapSize = GetWrapSize(texture.width, texture.height); return(wrapSize.Equals(new Vec2Int(texture.width, texture.height))); } return(true); }
public Entity GetNearestWorker(Vec2Int sourcePosition) { var nearestBuilder = GetNearestEntityOfType(sourcePosition, PlayerType.My, EntityType.BuilderUnit); // var nearestEntity = MyUnitsWorkers.Except(MyUnitsBusyWorkers) // .OrderBy(e => GetDistance(e.Position, sourcePosition)) // .First(); // // MyUnitsBusyWorkers.Add(nearestEntity); return(nearestBuilder); }
public static List <Vec2Int> Neighbors(this Vec2Int p, int size) { var neighbors = new List <Vec2Int>(); // up if (p.Y - 1 >= 0) { for (int i = 0; i < size; i++) { if (p.X + i < 80) { neighbors.Add(new Vec2Int(p.X + i, p.Y - 1)); } } } // right if (p.X - 1 >= 0) { for (int i = 0; i < size; i++) { if (p.Y + i < 80) { neighbors.Add(new Vec2Int(p.X - 1, p.Y + i)); } } } // down if (p.Y + size < 80) { for (int i = 0; i < size; i++) { if (p.X + i < 80) { neighbors.Add(new Vec2Int(p.X + i, p.Y + size)); } } } // left if (p.X + size < 80) { for (int i = 0; i < size; i++) { if (p.Y + i < 80) { neighbors.Add(new Vec2Int(p.X + size, p.Y + i)); } } } return(neighbors); }
public World() { Zero = new Vec2Int(0, 0); // Points = new List<Vec2Int>(); // for (int x = 0; x < 80; x++) // { // for (int y = 0; y < 80; y++) // { // Points.Add(new Vec2Int(x, y)); // } // } }
public void UpdateGraphicalTile(int tileIndex, Vec2Int xz, int neighborIndex) { TileObject tilePiece = CacheManager.Singleton.RequestGroundTile(); //tilePiece.transform.parent = this.transform; //tilePiece.transform.position = new Vector3(xz.x + tilePiece.defaultOffset.x, tilePiece.defaultOffset.y, xz.y + tilePiece.defaultOffset.z); //tilePiece.gameObject.SetActive(true); tilePiece.AssignToPosition(xz, 0f, true); SetTileGO(tileIndex, tilePiece); }
public void Init(Vec2Int dim, GroundManager.GroundData groundData) { m_groundTileDim = dim; m_associatedGroundData = groundData; m_groundTilesGOs = new BaseGroundObject[m_groundTileDim.x * m_groundTileDim.y]; m_tempSelectHolograms = new List <HologramObject>(); m_selectedHolograms = new List <HologramObject>(); m_tempSelectedTiles = new List <Vec2Int>(); m_selectedTiles = new List <Vec2Int>(); SetUpDebug(); }
static Vec2Int GetStartPos(Vec2Int wrap, int texWid, int texHei, TextAnchor anchor) { int left = (wrap.x - texWid) / 2; int top = (wrap.y - texHei) / 2; Vec2Int start = new Vec2Int(); switch (anchor) { case TextAnchor.LowerLeft: break; case TextAnchor.LowerCenter: start.x = left; break; case TextAnchor.LowerRight: start.x = wrap.x - texWid; break; case TextAnchor.MiddleLeft: start.y = top; break; case TextAnchor.MiddleCenter: start.x = left; start.y = top; break; case TextAnchor.MiddleRight: start.x = wrap.x - texWid; start.y = top; break; case TextAnchor.UpperLeft: start.y = wrap.y - texHei; break; case TextAnchor.UpperCenter: start.x = left; start.y = wrap.y - texHei; break; case TextAnchor.UpperRight: start.x = wrap.x - texWid; start.y = wrap.y - texHei; break; } return(start); }
public override void AssignToPosition(Vec2Int position, float rot, bool asHologram) { base.AssignToPosition(position, rot, asHologram); if (asHologram) { tileArt.renderer.material = PrefabAssets.Singleton.hologramMat; ToggleCollider(false); } else { ToggleCollider(true); } }
public override bool Equals(object obj) { if (obj is Vector2) { Vector2 vec = (Vector2)obj; return(this.x == (int)vec.x && this.y == (int)vec.y); } else if (obj is Vec2Int) { Vec2Int vec = obj as Vec2Int; return(this.x == vec.x && this.y == vec.y); } return(false); }
void MouseInput() { if (Input.GetMouseButton(0)) { Vector3 aimPos = CameraManager.Singleton.worldCamera.WorldPointFromMouse(); Vec2Int tilePos = GroundManager.Singleton.ConvertWorldPositionToTile(aimPos); GroundManager.GroundTileType tileType = GroundManager.Singleton.ClientData.GetTileType(tilePos); Debug.Log(string.Format("Tile pos {0} type {1}", tilePos, tileType)); GroundManager.Singleton.Client_AttemptBuildTile(this, tilePos, aimPos); } }
public override void AssignToPosition(Vec2Int position, float rot, bool asHologram) { base.AssignToPosition(position, rot, asHologram); if (asHologram) { SetMaterial(PrefabAssets.Singleton.doorHologramMat); ToggleCollider(false); } else { SetMaterial(PrefabAssets.Singleton.doorMatGray); ToggleCollider(true); } }
public override void generateOnHeightMap(ref float[,] _heightmap, bool _alterHeightmap) { int width = GetComponent<ProceduralMesh>().PointsNum1D; float cumulativeHeight = 0; int numStarts = numRivers; float[] highPoints = new float[numStarts]; Vec2Int[] highPointIndices = new Vec2Int[numStarts]; float highPt = float.MinValue; Vec2Int highPtIdx = new Vec2Int(); float ceil = float.MaxValue; for (int start = 0; start < numStarts; ++start) { bool foundStart = false; for (int i = 0; i < width; i++) { for (int j = 0; j < width; j++) { float height = _heightmap [i, j]; if (height > highPt && height < ceil) { //if (height > 0.4f && Random.Range(0,100) > 80) { if (!GetComponent<ProceduralMesh> ().getTerrainPresence (i, j)) continue; // Check how close this is to the other start points if (start != 0) { bool tooClose = false; Vector2 newV = new Vector2((float)i, (float)j); for(int prv = start-1; prv >= 0; prv--) { Vector2 lastV = new Vector2((float)highPointIndices[prv].x, (float)highPointIndices[prv].y); if(Mathf.Abs(Vector2.Distance(lastV,newV)) < 40.0f) { tooClose = true; break; } } if(tooClose) continue; } highPt = height; highPtIdx.x = i; highPtIdx.y = j; foundStart = true; } } } ceil = highPt; highPoints[start] = highPt; highPointIndices[start] = highPtIdx; highPt = float.MinValue; } for (int start = 0; start < numStarts; ++start) { highPt = highPoints[start]; highPtIdx = highPointIndices[start]; int k = highPtIdx.x; int L = highPtIdx.y; // Look for the lowest neighbour and go that way and repeat until we hit a ditch or fall off the edge Vec2Int[] nei = new Vec2Int[8]; List<Vec2Int> visited = new List<Vec2Int> (); float velocity = 0.0f; float lastHeight = highPt; while (k < width && k > 0 && L < width && L > 0) { visited.Add (new Vec2Int (k, L)); /* where x is k,L and 0-7 are indexes of nei 2 3 4 1 x 5 0 7 6 */ nei [0] = new Vec2Int (k - 1, L - 1); nei [1] = new Vec2Int (k - 1, L); nei [2] = new Vec2Int (k - 1, L + 1); nei [3] = new Vec2Int (k, L + 1); nei [4] = new Vec2Int (k + 1, L + 1); nei [5] = new Vec2Int (k + 1, L); nei [6] = new Vec2Int (k + 1, L + 1); nei [7] = new Vec2Int (k, L - 1); Vec2Int lowIdxs = new Vec2Int (); lowIdxs.x = -1; lowIdxs.y = -1; float lowHei = lastHeight; int lowIdx = -1; List<float> lowHeis = new List<float>(); List<Vec2Int> lowIndices = new List<Vec2Int>(); for (int m = 0; m < 8; ++m) { if (nei [m].x >= width || nei [m].x < 0) continue; if (nei [m].y >= width || nei [m].y < 0) continue; float height = _heightmap [nei [m].x, nei [m].y]; if ((height < lowHei || height - lowHei < velocity) && !visited.Any (v => v == nei [m])) { lowHeis.Add(height); lowIndices.Add(nei [m]); //velocity *= 0.75f; } else if ( !visited.Any (v => v == nei [m]) ) { Debug.LogFormat("dh: {0}", height - lowHei); } } // TODO: needs to be able to get over small if(lowHeis.Count() == 0) break; int idx = Random.Range(0,lowHeis.Count()); if(useLowestNei) idx = lowHeis.IndexOf( lowHeis.Min() ); lowIdxs = lowIndices[idx]; lowHei = lowHeis[idx]; if (!GetComponent<ProceduralMesh> ().getTerrainPresence (lowIdxs.x, lowIdxs.y)) break; k = lowIdxs.x; L = lowIdxs.y; if (lowIdxs.x == -1 && lowIdxs.y == -1) break; /*TODO: * Velocity creates wider river * Uphil turns river * Random chance to turn (& slow?) * Uphil slows river * Flooding areas * Overflow? Merging? * Turn initially? Bias 'off' straight down? * VFX */ velocity += lastHeight - _heightmap [k, L]; velocity = Mathf.Min(velocityMax, velocity); lastHeight = _heightmap [k, L]; if (velocity < 0.0f) Debug.Assert (velocity > 0.0f); float heightLoss = heightLossMul * velocity; _heightmap [k, L] -= heightLoss; // Lower the neighbours too for (int m = 0; m < 8; ++m) { _heightmap [nei[m].x, nei[m].y] -= heightLoss * neighbourLossMul; } Debug.LogFormat("velocity: {0}", velocity); } } // // float averageHeight = cumulativeHeight / (width * width); // float topThreeQuaters = averageHeight + (averageHeight * 0.5f); // // // Point startingPoint = null; // bool foundGoodStart = false; // while (!foundGoodStart) // { // int randX = Random.Range(0,width); // int randY = Random.Range(0,width); // // float chosenHeight = _heightmap[randX,randY]; // if (chosenHeight > topThreeQuaters && GetComponent<ProceduralMesh>().arrayValidData[randX+randY*width]) // { // startingPoint = new Point(); // startingPoint.x = randX; // startingPoint.y = randY; // startingPoint.deadPoint = false; // pointList.Add(startingPoint); // foundGoodStart = true; // } // } // // bool foundEdge = false; // // while(!foundEdge) // { // Point lastPoint = null; // int pointIndex = pointList.Count - 1; // for (pointIndex = pointList.Count - 1; pointIndex >= 0 && lastPoint == null; pointIndex--) // { // if (!pointList[pointIndex].deadPoint) // { // lastPoint = pointList[pointIndex]; // } // } // if (lastPoint == null) // { // Debug.Log("Ran out of points! (index: " + pointIndex + " , count: " + pointList.Count); // foundEdge = true; // break; // } // float bestHeightDifference = 0.0f; // Point bestPoint = null; // for (int i = lastPoint.x-1; i <= lastPoint.x+1; i++) // { // for (int j =lastPoint.y-1; j <= lastPoint.y+1; j++) // { // if (i >= 0 && i < width && j >= 0 &&j < width) // { // bool foundPoint = false; // foreach (Point point in pointList) // { // if (point.x == i && point.y == j) // { // foundPoint = true; // } // } // //if we haven't already got this point get the height diff. // if (!foundPoint) // { // float testHeight = _heightmap[i, j]; // float currentHeight = _heightmap[lastPoint.x, lastPoint.y]; // float heightDiff = testHeight - currentHeight; // if (heightDiff < 0.0 && heightDiff < bestHeightDifference ) // { // bestHeightDifference = heightDiff; // bestPoint = new Point(); // bestPoint.x = i; // bestPoint.y = j; // bestPoint.nextPoint = null; // bestPoint.deadPoint = false; // } // } // } // } // } // if (bestPoint == null) // { // Debug.Log("Dead point at " + lastPoint.x +"," + lastPoint.y +" after iteration num: " + pointList.Count); // foundEdge = true; // lastPoint.deadPoint = true; // } // else // { // lastPoint.nextPoint = bestPoint; // pointList.Add(bestPoint); // if (bestPoint.x == 0 || bestPoint.x == width - 1 || bestPoint.y == 0 || bestPoint.y == width - 1) // { // foundEdge = true; // Debug.Log("found edge after " + pointList.Count + "iterations"); // } // } // } // // float[,] alterMap = new float[width,width]; // for (int i = 0; i < width; i++) // { // for (int j = 0; j < width; j++) // { // alterMap[i,j]=0.0f; // } // } // if (_alterHeightmap) // { // Point currentPoint = pointList[0]; // Point nextPoint = currentPoint.nextPoint; // float riverWidth = 5.0f; // while (currentPoint!=null) // { // alterMap[currentPoint.x,currentPoint.y] = heightModifer; // if (nextPoint!=null) // { // Vector2 origin = new Vector2(currentPoint.x, currentPoint.y); // Vector2 perpDirection = new Vector2(-nextPoint.y - currentPoint.y, nextPoint.x - currentPoint.x); // perpDirection.Normalize(); // for (float currentWidth = -riverWidth;currentWidth<riverWidth;currentWidth+=0.5f) // { // Vector2 position = origin+perpDirection*currentWidth; // int xIndex = Mathf.FloorToInt(position.x); // int yIndex = Mathf.FloorToInt(position.y); // alterMap[xIndex, yIndex] = heightModifer; // } // } // currentPoint = nextPoint; // } // for (int i = 0; i < width; i++) // { // for (int j = 0; j < width; j++) // { // _heightmap[i, j] += alterMap[i, j]; // } // } // } }
// リンク方向の端のノードIDを算出する(フレームノードを除く) Vec2Int SearchLimitNodeRemoveFrame(Vec2Int id, _eLinkDir dir) { //Log.Debug("SearchLimitNodeRemoveFrame : " + id + "/" + dir); Vec2Int limitNodeID = id; Vec2Int limitNodeIDTmp = GetDirNodeRemoveFrame(limitNodeID, dir); while (limitNodeIDTmp.x > -1) { limitNodeID = limitNodeIDTmp; limitNodeIDTmp = GetDirNodeRemoveFrame(limitNodeID, dir); } return limitNodeID; }
// 任意の座標に最も近いノードのIDを、座標を基準に検索する Vec2Int SearchNearNode(Vector3 pos) { //Log.Debug("SerchNearNode : " + pos); Vec2Int id = new Vec2Int(-1, -1); float minDist = 99999.0f; // 検索処理 for (int i = 0; i < col; ++i) { for (int j = 0; j < AdjustRow(i); ++j) { float dist = Vector3.Distance(pos, nodePlacePosList[i][j]); if (dist < minDist) { minDist = dist; id.x = j; id.y = i; } } } return id; }
/// <summary> /// Returns the texture offset needed to change a material to the item given. /// Assumes texture is a uniform spritesheet. /// Assumes you give it the right gridsize. /// Assumes you give it an index within range. /// </summary> /// <param name="mat">The material to change.</param> /// <param name="gridSize">Number of rows and columns.</param> /// <param name="index">Which item in grid to change to.</param> /// <returns>The offset.</returns> public static Vector2 GetTexGridOffset(Material mat, Vec2Int gridSize, int index) { float rowOffset = (index % gridSize.x) * mat.mainTextureScale.x; float colOffset = (1 - mat.mainTextureScale.y) - ((index / gridSize.y) * mat.mainTextureScale.y); return new Vector2(rowOffset, colOffset); }
// ノードのスライド移動処理 void SlideNodes() { ////Log.Debug("SlideNodes"); // スライド対象となるノードの準備 Vector2 deltaSlideDist = tapPos - prevTapPos; // 前回フレームからのスライド量 float checkDir = 0.0f; // スライド方向チェック用 switch (slideDir) { case _eSlideDir.LEFT: case _eSlideDir.RIGHT: // スライド方向を再計算 if (tapPos.x - prevTapPos.x < 0.0f) { // スライド方向が前フレームと違ったら更新 if (slideDir != _eSlideDir.LEFT) { Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; slideDir = _eSlideDir.LEFT; } } else if (tapPos.x - prevTapPos.x > 0.0f) { if (slideDir != _eSlideDir.RIGHT) { Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; slideDir = _eSlideDir.RIGHT; } } break; case _eSlideDir.LEFTUP: case _eSlideDir.RIGHTDOWN: // スライド方向を再計算 checkDir = AddVectorFunctions.Vec2Cross(deltaSlideDist, slideLeftUpPerNorm); if (checkDir < 0.0f) { if (slideDir != _eSlideDir.LEFTUP) { Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; slideDir = _eSlideDir.LEFTUP; } } else if (checkDir > 0.0f) { if (slideDir != _eSlideDir.RIGHTDOWN) { Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; slideDir = _eSlideDir.RIGHTDOWN; } } break; case _eSlideDir.RIGHTUP: case _eSlideDir.LEFTDOWN: // スライド方向を再計算 checkDir = AddVectorFunctions.Vec2Cross(deltaSlideDist, slideLeftDownPerNorm); if (checkDir < 0.0f) { if (slideDir != _eSlideDir.LEFTDOWN) { Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; slideDir = _eSlideDir.LEFTDOWN; } } else if (checkDir > 0.0f) { if (slideDir != _eSlideDir.RIGHTUP) { Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; slideDir = _eSlideDir.RIGHTUP; } } break; default: break; } // ノードを移動 AdjustSlideNodePosition(); }
FinNode(Node tgt) { ID = tgt.NodeID; Rot = tgt.RotCounter; Temp = tgt.Temp; }
//位置と方向から、指定ノードに隣り合うノードのrowとcolを返す //なければ、(-1,-1)を返す // フレームノードを除く public Vec2Int GetDirNodeRemoveFrame(Vec2Int nodeID, _eSlideDir toSlideDir) { return GetDirNodeRemoveFrame(nodeID.x, nodeID.y, toSlideDir); }
public void TapRelease() { // タップに成功していなければ未処理 if (!isTap) return; // タップ終了 isTap = false; ////Log.Debug("MouseButtonUp"); if (isSlide) { AdjustNodeStop(); isSlideEnd = true; tapNodeID = Vec2Int.zero; } else { if (tapNodeID.x > -1) { audioSources[(int)_eAudioNumber.ROTATE].Play(); gameNodeScripts[tapNodeID.y][tapNodeID.x].RotationNode(); _isNodeAction = true; } } }
// 移動を終了するノードの位置を調整する void AdjustNodeStop() { ////Log.Debug("AdjustNodeStop"); Vec2Int nearNodeID = SearchNearNode(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position); Vec2Int nextNodeID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(slideDir)); _eSlideDir reverseDir = ReverseDirection(slideDir); Vector2 pos = new Vector2(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.x, gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.y); Vector2 standardPos = new Vector2(nodePlacePosList[nearNodeID.y][nearNodeID.x].x, nodePlacePosList[nearNodeID.y][nearNodeID.x].y); // スライド方向を更新 if (pos.x != standardPos.x || pos.y != standardPos.y) { _eSlideDir checkDir = CheckSlideDir(pos, standardPos); if (slideDir != checkDir) { slideDir = checkDir; Vec2Int tmp = slidingLimitNodeID; slidingLimitNodeID = slidingReverseLimitNodeID; slidingReverseLimitNodeID = tmp; } } // スライド方向のノードに、スライド終了を通知 while (nextNodeID.x > -1) { gameNodeScripts[nextNodeID.y][nextNodeID.x].EndSlide(); nextNodeID = GetDirNode(nextNodeID, reverseDir); } // 回り込み処理 CheckSlideOutLimitNode(); LoopBackNode(); // 移動処理 switch (slideDir) { case _eSlideDir.LEFT: case _eSlideDir.RIGHT: pos = standardPos; // タップしているノードを移動 gameNodeScripts[tapNodeID.y][tapNodeID.x].SlideNode(slideDir, standardPos); // タップしているノードより左側のノードを移動 nextNodeID = GetDirNode(tapNodeID, _eLinkDir.L); for (int i = 1; nextNodeID.x > -1; ++i) { pos.x = standardPos.x - moveNodeDistAbs.x * i; gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos); nextNodeID = GetDirNode(nextNodeID, _eLinkDir.L); } // タップしているノードより右側のノードを移動 nextNodeID = GetDirNode(tapNodeID, _eLinkDir.R); for (int i = 1; nextNodeID.x > -1; ++i) { pos.x = standardPos.x + moveNodeDistAbs.x * i; gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos); nextNodeID = GetDirNode(nextNodeID, _eLinkDir.R); } break; case _eSlideDir.LEFTUP: case _eSlideDir.RIGHTDOWN: // タップしているノードを移動 gameNodeScripts[tapNodeID.y][tapNodeID.x].SlideNode(slideDir, standardPos); // タップしているノードより左上側のノードを移動 nextNodeID = GetDirNode(tapNodeID, _eLinkDir.LU); for (int i = 1; nextNodeID.x > -1; ++i) { pos.x = standardPos.x - moveNodeDistAbs.x * i; pos.y = standardPos.y + moveNodeDistAbs.y * i; gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos); nextNodeID = GetDirNode(nextNodeID, _eLinkDir.LU); } // タップしているノードより右下側のノードを移動 nextNodeID = GetDirNode(tapNodeID, _eLinkDir.RD); for (int i = 1; nextNodeID.x > -1; ++i) { pos.x = standardPos.x + moveNodeDistAbs.x * i; pos.y = standardPos.y - moveNodeDistAbs.y * i; gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos); nextNodeID = GetDirNode(nextNodeID, _eLinkDir.RD); } break; case _eSlideDir.RIGHTUP: case _eSlideDir.LEFTDOWN: // タップしているノードを移動 gameNodeScripts[tapNodeID.y][tapNodeID.x].SlideNode(slideDir, standardPos); // タップしているノードより右上側のノードを移動 nextNodeID = GetDirNode(tapNodeID, _eLinkDir.RU); for (int i = 1; nextNodeID.x > -1; ++i) { pos.x = standardPos.x + moveNodeDistAbs.x * i; pos.y = standardPos.y + moveNodeDistAbs.y * i; gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos); nextNodeID = GetDirNode(nextNodeID, _eLinkDir.RU); } // タップしているノードより左下側のノードを移動 nextNodeID = GetDirNode(tapNodeID, _eLinkDir.LD); for (int i = 1; nextNodeID.x > -1; ++i) { pos.x = standardPos.x - moveNodeDistAbs.x * i; pos.y = standardPos.y - moveNodeDistAbs.y * i; gameNodeScripts[nextNodeID.y][nextNodeID.x].SlideNode(slideDir, pos); nextNodeID = GetDirNode(nextNodeID, _eLinkDir.LD); } break; default: break; } }
//移動したいノードを確定 //ドラッグを算出し移動したい方向列を確定 //ドラッグされている間、列ごと移動、 //タップ点からスワイプ地点まで座標の差分を算出し //列のすべてのノードをその位置へ移動させる //離すと一番近いノード確定位置まで調整 public void StartSlideNodes(Vec2Int nextNodeID, _eSlideDir newSlideDir) { ////Log.Debug("StartSlideNodes : " + nextNodeID + " / " + newSlideDir); moveNodeDist = new Vector2(gameNodePrefabs[nextNodeID.y][nextNodeID.x].transform.position.x, gameNodePrefabs[nextNodeID.y][nextNodeID.x].transform.position.y) - new Vector2(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.x, gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position.y); // スライド方向ベクトル兼移動量を算出 moveNodeInitPos = gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position; // ノードの移動開始位置を保存 // スライド方向を設定 slideDir = newSlideDir; // 絶対値を算出 moveNodeDistAbs.x = Mathf.Abs(moveNodeDist.x); moveNodeDistAbs.y = Mathf.Abs(moveNodeDist.y); // スライド開始準備 Vec2Int nextID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(slideDir)); _eSlideDir reverseDir = ReverseDirection(slideDir); while (nextID.x > -1) { gameNodeScripts[nextID.y][nextID.x].StartSlide(); nextID = GetDirNode(nextID, reverseDir); } // スライド方向の端のノードIDを算出 slidingLimitNodeID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(slideDir)); slidingReverseLimitNodeID = SearchLimitNode(tapNodeID, ConvertSlideDirToLinkDir(ReverseDirection(slideDir))); // タップしているノードの位置と、タップしている位置との距離を算出 tapPosMoveNodePosDist = moveNodeDist.normalized * Vector2.Dot(moveNodeDist.normalized, startTapPos - moveNodeInitPos); }
public void ReplaceNodeFever() { //Log.Debug("ReplaceNodeFever"); //foreach (var xList in gameNodeScripts) //{ // foreach (var it in xList) // { // it.SetNodeType(NodeTemplate.GetTempFromBranchRandom(NodeTemp, 1), 0); // } //} if (FinishNodeList != null && FinishNodeList.Count > 0) { #region // 過去記憶版 var UseTree = FinishNodeList[RandomEx.RangeforInt(0, FinishNodeList.Count)]; foreach (var it in UseTree) { gameNodeScripts[it.ID.y][it.ID.x].SetNodeType(it.Temp, it.Rot); }; int mut = RandomEx.RangeforInt(0, UseTree.Count); gameNodeScripts[UseTree[mut].ID.y][UseTree[mut].ID.x].RotationNode(true, true); if (FinishNodeList.Count > 15) { FinishNodeList.RemoveRange(0, 10); } #endregion } else { #region // 自己生成版 string str = "ReplaceNodeFeverLog\n"; int targetNum = RandomEx.RangeforInt(3, 9); str += "Target : " + targetNum; List<Node> lstTree = new List<Node>(); int x = RandomEx.RangeforInt(2, 5); int y = 1; _eLinkDir Dir = _eLinkDir.LD; int RotationNum; while (lstTree.Count < targetNum) { str += "\nCheck" + gameNodeScripts[y][x].ToString() + "\n"; gameNodeScripts[y][x].SetNodeType(NodeTemplate.GetTempFromBranchRandom(NodeTemp, 2), 0); str += "SetNode : " + gameNodeScripts[y][x].bitLink.ToStringEx() + " / " + gameNodeScripts[y][x].Temp.ToString() + "\n"; int CheckLinkNum = 0; bool Decide = false; ///<summary> /// 不正な回転 or 回転できなかった処理が存在 ///</summary> RotationNum = 0; while (!Decide && gameNodeScripts[y][x].bitLink.Count > CheckLinkNum) { while (!gameNodeScripts[y][x].bitLink[(int)Dir]) { gameNodeScripts[y][x].RotationNode(true); RotationNum++; } str += "Rot : " + RotationNum + " / " + gameNodeScripts[y][x].bitLink.ToStringEx() + "\n"; Vec2Int nextNode = new Vec2Int(-1, -1); _eLinkDir NextDir = Dir; for (int n = 0; n < 6; n++) { if (n == (int)Dir) { continue; } if (gameNodeScripts[y][x].bitLink[n]) { nextNode = GetDirNode(x, y, (_eLinkDir)n); if (nextNode.x == -1 || gameNodeScripts[nextNode.y][nextNode.x].IsOutPuzzle) { nextNode.x = x; nextNode.y = y; CheckLinkNum++; if (n == 5) { str += "Failed"; break; } } str += "Find" + ((_eLinkDir)n).ToString(); Decide = true; NextDir = ReverseDirection((_eLinkDir)n); } } gameNodeScripts[y][x].SetNodeType(gameNodeScripts[y][x].Temp, RotationNum); x = nextNode.x; y = nextNode.y; Dir = NextDir; lstTree.Add(gameNodeScripts[y][x]); } } // 枝に蓋をする gameNodeScripts[y][x].SetNodeType(NodeTemplate.GetTempFromBranchRandom(NodeTemp, 1), 0); RotationNum = 0; while (!gameNodeScripts[y][x].bitLink[(int)Dir]) { gameNodeScripts[y][x].RotationNode(true); RotationNum++; } gameNodeScripts[y][x].RotationNode(true, true); gameNodeScripts[y][x].SetNodeType(gameNodeScripts[y][x].Temp, RotationNum == 0 ? 5 : RotationNum - 1); lstTree.Add(gameNodeScripts[y][x]); Debug.Log(str); #endregion } CheckLink(); }
//指定した位置のノードのスクリプトをもらう public Node GetNodeScript(Vec2Int nodeID) { return gameNodeScripts[nodeID.y][nodeID.x]; }
//スライド操作時にスライドノードを指定して消去 public void RemoveWithNode(Vec2Int nodeID) { //IDが一致するものを消去 List<UnChainObject> delList; delList = unChainCubeList.FindAll(x => { if (x.nodeVec.x == nodeID.x && x.nodeVec.y == nodeID.y) return true; else return false; }); foreach (var ucObj in delList) { ucObj.Vanish(); unChainCubeList.Remove(ucObj); } }
// Use this for initialization void Start() { ////Log.Debug("Start"); //音声データを取得 添字をenum化すべきか audioSources = GetComponents<AudioSource>(); /*if (audioSources.Length != (int)_eAudioNumber.MAX) print("音声取得に失敗");*/ // ----- プレハブデータを Resources から取得 gameNodePrefab = Resources.Load<GameObject>(gameNodePrefabPath); frameNodePrefab = Resources.Load<GameObject>(frameNodePrefabPath); gameArrowPrefab = Resources.Load<GameObject>(gameArrowPrefabPath); // ----- スプライトデータを Resources から取得 gameNodeSprite = Resources.LoadAll<Sprite>(gameNodeSpritePath); nodeMaskSprite = Resources.LoadAll<Sprite>(nodeMaskSpritePath); frameNodeSprite = Resources.LoadAll<Sprite>(frameNodeSpritePath); // GameEffect スクリプトを取得 gameEffect = transform.GetComponent<GameEffect>(); // ----- ノード準備 NodeTemplate.AllCalc(NodeTemp); InitNode(); //開始演出が終わるまでは操作を受け付けない SetSlideAll(true); // スライドベクトルの垂線を算出 Vector3 leftUp = gameNodePrefabs[0][1].transform.position - gameNodePrefabs[0][0].transform.position; Vector3 leftDown = gameNodePrefabs[1][1].transform.position - gameNodePrefabs[0][0].transform.position; Matrix4x4 mtx = Matrix4x4.identity; mtx.SetTRS(new Vector3(0.0f, 0.0f, 0.0f), Quaternion.Euler(0.0f, 0.0f, 90.0f), new Vector3(1.0f, 1.0f, 1.0f)); leftUp = mtx.MultiplyVector(leftUp).normalized; leftDown = mtx.MultiplyVector(leftDown).normalized; slideLeftUpPerNorm = new Vector2(leftUp.x, leftUp.y); slideLeftDownPerNorm = new Vector2(leftDown.x, leftDown.y); // SE準備 cumSlideIntervalPlaySE = 0.0f; // ----- インプット処理 Observable .EveryUpdate() .Where(_ => Input.GetMouseButton(0)) .Subscribe(_ => { // タップに成功していなければ未処理 if (!isTap) { return; } Vector3 worldTapPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); // スライド処理 if (isSlide) { prevTapPos = tapPos; tapPos = new Vector2(worldTapPos.x, worldTapPos.y); SlideNodes(); CheckSlideOutLimitNode(); LoopBackNode(); return; } // スライド判定 if (tapNodeID.x > -1 && startTapPos != (Vector2)worldTapPos) { _eSlideDir dir = CheckSlideDir(startTapPos, new Vector2(worldTapPos.x, worldTapPos.y)); Vec2Int nextNodeID = GetDirNode(tapNodeID, dir); if (nextNodeID.x > -1) { if (Vector3.Distance(gameNodePrefabs[tapNodeID.y][tapNodeID.x].transform.position, worldTapPos) > Vector3.Distance(gameNodePrefabs[nextNodeID.y][nextNodeID.x].transform.position, worldTapPos)) { isSlide = true; _isNodeAction = true; StartSlideNodes(nextNodeID, dir); } } } }) .AddTo(this.gameObject); Observable .EveryUpdate() .Where(_ => Input.GetMouseButtonDown(0)) .Subscribe(_ => { // スライド中なら未処理 if (isSlide) return; if (pauseScript.pauseState == _ePauseState.PAUSE) return; if (levelControllerScript.LevelState != _eLevelState.STAND) return; // タップ成功 isTap = true; ////Log.Debug("MouseButtonDown"); Vector3 worldTapPos = Camera.main.ScreenToWorldPoint(Input.mousePosition); startTapPos = new Vector2(worldTapPos.x, worldTapPos.y); // タップしているノードのIDを検索 tapNodeID = SearchNearNodeRemoveFrame(worldTapPos); }) .AddTo(this.gameObject); Observable .EveryUpdate() .Where(_ => Input.GetMouseButtonUp(0)) .Subscribe(_ => TapRelease()/*{ // タップに成功していなければ未処理 if (!isTap) return; // タップ終了 isTap = false; //Log.Debug("MouseButtonUp"); if (isSlide) { AdjustNodeStop(); isSlideEnd = true; tapNodeID = Vec2Int.zero; } else { if (tapNodeID.x > -1) { audioSources[(int)_eAudioNumber.ROTATE].Play(); gameNodeScripts[tapNodeID.y][tapNodeID.x].RotationNode(); _isNodeAction = true; } } }*/) .AddTo(gameObject); // ノードのアニメーション終了と同時に接続チェック Observable .EveryUpdate() .Select(x => !(IsNodeAction) && !(isNodeLock)) .DistinctUntilChanged() .Where(x => x) .ThrottleFrame(3) .Subscribe(x => { CheckLink(); }) .AddTo(gameObject); // ノードがアクション中かチェック Observable .EveryUpdate() .Where(_ => _isNodeAction) .Subscribe(_ => { for (int i = 0; i < col; ++i) { foreach (var nodes in gameNodeScripts[i]) { if (nodes.IsAction) return; } } _isNodeAction = false; }) .AddTo(gameObject); // ノードがスライド終了処理中かチェック Observable .EveryUpdate() .Where(_ => isSlideEnd) .Subscribe(_ => { for (int i = 0; i < col; ++i) { foreach (var nodes in gameNodeScripts[i]) { if (nodes.IsSlideEnd) { return; } } } isSlideEnd = false; if (isSlide) { isSlide = false; slideDir = _eSlideDir.NONE; cumSlideIntervalPlaySE = 0.0f; } }) .AddTo(gameObject); // SE再生処理 Observable .EveryUpdate() .Where(_ => isSlide) .Subscribe(_ => { if(cumSlideIntervalPlaySE > slideIntervalPlaySE) { audioSources[(int)_eAudioNumber.SLIDE].Play(); cumSlideIntervalPlaySE = 0.0f; } }) .AddTo(gameObject); Observable .NextFrame() .Subscribe(_ => CheckLink(true, true)) .AddTo(this); }
// ゲームの画面外にはみ出したノードを逆側に移動する void LoopBackNode() { ////Log.Debug("LoopBackNode"); if (gameNodeScripts[slidingLimitNodeID.y][slidingLimitNodeID.x].IsOutScreen) { gameNodeScripts[slidingLimitNodeID.y][slidingLimitNodeID.x].IsOutScreen = false; // はみ出たノードを逆側に移動し、ノード情報をソートする var dir = slideDir; var outNodeID = slidingLimitNodeID; GameObject outNode = gameNodePrefabs[outNodeID.y][outNodeID.x]; Node outNodeScript = gameNodeScripts[outNodeID.y][outNodeID.x]; _eSlideDir reverseDir = ReverseDirection(dir); Vector3 pos = Vector3.zero; // ノード入れ替え処理(スライド方向に置換していく) Vec2Int limitNodeID = outNodeID; Vec2Int prevSearchID = outNodeID; while (GetDirNode(limitNodeID, reverseDir).x > -1) { prevSearchID = limitNodeID; limitNodeID = GetDirNode(limitNodeID, reverseDir); CopyNodeInfo(prevSearchID.x, prevSearchID.y, gameNodePrefabs[limitNodeID.y][limitNodeID.x], gameNodeScripts[limitNodeID.y][limitNodeID.x]); } CopyNodeInfo(limitNodeID.x, limitNodeID.y, outNode, outNodeScript); // 位置を調整 prevSearchID = GetDirNode(limitNodeID, dir); pos = gameNodePrefabs[prevSearchID.y][prevSearchID.x].transform.position; switch (dir) { case _eSlideDir.LEFT: pos = gameNodePrefabs[tapNodeID.y][AdjustRow(tapNodeID.y) - 2].transform.position; pos.x += moveNodeDistAbs.x; break; case _eSlideDir.RIGHT: pos = gameNodePrefabs[tapNodeID.y][1].transform.position; pos.x -= moveNodeDistAbs.x; break; case _eSlideDir.LEFTUP: pos.x += moveNodeDistAbs.x; pos.y -= moveNodeDistAbs.y; break; case _eSlideDir.LEFTDOWN: pos.x += moveNodeDistAbs.x; pos.y += moveNodeDistAbs.y; break; case _eSlideDir.RIGHTUP: pos.x -= moveNodeDistAbs.x; pos.y -= moveNodeDistAbs.y; break; case _eSlideDir.RIGHTDOWN: pos.x -= moveNodeDistAbs.x; pos.y += moveNodeDistAbs.y; break; } gameNodeScripts[limitNodeID.y][limitNodeID.x].StopTween(); gameNodePrefabs[limitNodeID.y][limitNodeID.x].transform.position = pos; // 選択中のノードIDを更新 tapNodeID = GetDirNode(tapNodeID, dir); Vec2Int copyInNodeID = SearchLimitNodeRemoveFrame(tapNodeID, ConvertSlideDirToLinkDir(SlideDir)); Vec2Int copyOutNodeID = SearchLimitNodeRemoveFrame(tapNodeID, ConvertSlideDirToLinkDir(ReverseDirection(slideDir))); copyOutNodeID = GetDirNode(copyOutNodeID, ReverseDirection(slideDir)); gameNodeScripts[copyOutNodeID.y][copyOutNodeID.x].CopyParameter(gameNodeScripts[copyInNodeID.y][copyInNodeID.x]); } }
//位置と方向から、指定ノードに隣り合うノードのrowとcolを返す //なければ、(-1,-1)を返す public Vec2Int GetDirNode(Vec2Int nodeID, _eLinkDir toDir) { return GetDirNode(nodeID.x, nodeID.y, toDir); }