/// <summary> /// Move to ceter tile position in speed /// </summary> /// <param name="centerTilePosition"></param> /// <param name="speed"></param> public void MoveTo(Vector2 centerTilePosition, int speed) { _moveToBeginDestination = Map.ToPixelPosition(centerTilePosition) - GetHalfViewSize(); _moveSpeed = speed; IsInMoveTo = true; }
private static void AddVTypeFixedPOsitionMagicSprite(Character user, Magic magic, Vector2 origin, Vector2 destination, bool destroyOnEnd) { var direction = destination - origin; var directionIndex = Utils.GetDirectionIndex(direction, 8); var count = 3; if (magic.CurrentLevel > 3) { count += ((magic.CurrentLevel - 1) / 3) * 2; } var orgTile = PathFinder.FindNeighborInDirection(Map.ToTilePosition(origin), directionIndex); AddMagicSprite(GetFixedPositionMagicSprite(user, magic, Map.ToPixelPosition(orgTile), destroyOnEnd)); const float magicDelayMilliseconds = 60f; var leftVTile = orgTile; var rightVTile = orgTile; for (var i = 1; i < count; i++) { leftVTile = PathFinder.FindNeighborInDirection(leftVTile, (directionIndex + 7) % 8); rightVTile = PathFinder.FindNeighborInDirection(rightVTile, (directionIndex + 1) % 8); AddWorkItem(new WorkItem(i * magicDelayMilliseconds, GetFixedPositionMagicSprite(user, magic, Map.ToPixelPosition(leftVTile), destroyOnEnd))); AddWorkItem(new WorkItem(i * magicDelayMilliseconds, GetFixedPositionMagicSprite(user, magic, Map.ToPixelPosition(rightVTile), destroyOnEnd))); } }
private static void AddRegionFileMagicSprite(Character user, Magic magic, Vector2 origin, Vector2 destination, bool destroyOnEnd) { if (magic.RegionFile == null) { return; } var direction = destination - origin; var directionIndex = Utils.GetDirectionIndex(direction, 8); var items = magic.RegionFile.ContainsKey(directionIndex) ? magic.RegionFile[directionIndex] : magic.RegionFile[0]; //Make destination at tile center destination = Map.ToPixelPosition(Map.ToTilePosition(destination)); foreach (var item in items) { var magicSprite = GetFixedPositionMagicSprite(user, magic, destination + item.Offset, destroyOnEnd); if (item.Delay > 0) { AddWorkItem(new WorkItem(item.Delay, magicSprite)); } else { AddMagicSprite(magicSprite); } } }
private static void FillItems(List <Item> items, Vector2 beginPos, Layer layer, Dictionary <int, List <int> > delayInfo) { var beginPixelPosition = Map.ToPixelPosition(beginPos, false); for (var h = 0; h < layer.Height; h++) { for (var w = 0; w < layer.Width; w++) { var tileIndex = layer.Data[w + h * layer.Width]; if (tileIndex == 0) { continue; } var offset = Map.ToPixelPosition(w, h, false) - beginPixelPosition; if (delayInfo.ContainsKey(tileIndex)) { items.AddRange(delayInfo[tileIndex].Select(delay => new Item(offset, delay))); } else { items.Add(new Item(offset, 0)); } } } }
/// <summary> /// Bounce at wall, find wall tiles. /// </summary> /// <param name="direction"></param> /// <param name="worldPosition"></param> /// <param name="targetTilePosition"></param> /// <returns>Bouncing direction</returns> public static Vector2 BouncingAtWall(Vector2 direction, Vector2 worldPosition, Vector2 targetTilePosition) { if (direction == Vector2.Zero) { return(direction); } var dir = Utils.GetDirectionIndex(direction, 8); var checks = new[] { (dir + 2) % 8, (dir + 6) % 8, (dir + 1) % 8, (dir + 7) % 8 }; var get = 8; var neighbors = FindAllNeighbors(targetTilePosition); for (var i = 0; i < checks.Count(); i++) { if (Globals.TheMap.IsObstacleForMagic(neighbors[checks[i]])) { get = checks[i]; break; } } if (get == 8) { return(BouncingAtPoint(direction, worldPosition, Map.ToPixelPosition(targetTilePosition))); } var normal = Map.ToPixelPosition(targetTilePosition) - Map.ToPixelPosition(neighbors[get]); normal = Vector2.Normalize(new Vector2(-normal.Y, normal.X)); return(Vector2.Reflect(direction, normal)); }
/// <summary> /// Get line path without care obstacle. /// </summary> /// <param name="startTile">Start tile positon</param> /// <param name="endTile">End tile positon</param> /// <param name="maxTry">Max strep</param> /// <param name="tilePositon">If true, path position in path list is tile position.Otherwise is postion in world.</param> /// <returns>Path positition in world list.</returns> public static LinkedList <Vector2> GetLinePath(Vector2 startTile, Vector2 endTile, int maxTry, bool tilePositon = false) { if (startTile == endTile) { return(null); } var path = new LinkedList <Vector2>(); var frontier = new C5.IntervalHeap <Node <Vector2> >(); frontier.Add(new Node <Vector2>(startTile, 0f)); while (!frontier.IsEmpty) { if (maxTry-- < 0) { break; } var current = frontier.DeleteMin().Location; path.AddLast(tilePositon? current : Map.ToPixelPosition(current)); if (current == endTile) { break; } foreach (var neighbor in FindAllNeighbors(current)) { frontier.Add(new Node <Vector2>(neighbor, GetTilePositionCost(neighbor, endTile))); } } return(path); }
public Texture2D GetTileTextureAndRegion(int x, int y, int layer, ref Rectangle region) { if (!IsOk) { return(null); } var texture = GetTileTexture(x, y, layer); if (texture != null) { var position = Map.ToPixelPosition(x, y) - new Vector2(texture.Width / 2f, texture.Height - 16f); region = new Rectangle((int)position.X, (int)position.Y, texture.Width, texture.Height); } return(texture); }
private static LinkedList <Vector2> GetPath(Dictionary <Vector2, Vector2> cameFrom, Vector2 startTile, Vector2 endTile) { if (cameFrom.ContainsKey(endTile)) { var path = new LinkedList <Vector2>(); var current = endTile; path.AddFirst(Map.ToPixelPosition(current)); while (current != startTile) { current = cameFrom[current]; path.AddFirst(Map.ToPixelPosition(current)); } return(path); } return(null); }
private bool Init(Magic belongMagic, Character belongCharacter, Vector2 positionInWorld, float velocity, Vector2 moveDirection, bool destroyOnEnd) { if (belongMagic == null || belongCharacter == null) { _isDestroyed = true; return(false); } if (belongMagic.NoExplodeWhenLifeFrameEnd > 0) { destroyOnEnd = false; } else if (belongMagic.ExplodeWhenLifeFrameEnd > 0) { destroyOnEnd = true; } _destnationPixelPosition = positionInWorld; var texture = belongMagic.FlyingImage; switch (belongMagic.MoveKind) { case 15: texture = belongMagic.SuperModeImage; break; case 20: positionInWorld = Map.ToPixelPosition(belongCharacter.TilePosition); break; case 21: { var player = belongCharacter as Player; if (player != null && player.ControledCharacter != null) { player.ControledCharacter.ControledMagicSprite = this; } else { throw new Exception("Magic kind 21 internal error."); } } break; case 22: //Summon { var tilePosition = Map.ToTilePosition(positionInWorld); var finded = PathFinder.FindNonobstacleNeighborOrItself(belongCharacter, ref tilePosition); if (finded) { positionInWorld = Map.ToPixelPosition(tilePosition); } else { _isDestroyed = true; break; } if (belongCharacter.SummonedNpcsCount >= belongMagic.MaxCount) { //Reach max count belongCharacter.RemoveFirstSummonedNpc(); } var npc = NpcManager.AddNpc(belongMagic.NpcFile, (int)tilePosition.X, (int)tilePosition.Y, Utils.GetDirectionIndex(positionInWorld - belongCharacter.PositionInWorld, 8)); belongCharacter.AddSummonedNpc(npc); if (belongCharacter.IsPlayer || belongCharacter.IsFighterFriend) { npc.Relation = (int)Character.RelationType.Friend; } else { npc.Kind = (int)Character.CharacterKind.Fighter; npc.Relation = (int)Character.RelationType.Enemy; } npc.SummonedByMagicSprite = this; _summonedNpc = npc; } break; } if (belongMagic.CarryUser > 0) { belongCharacter.MovedByMagicSprite = this; } Set(positionInWorld, velocity, texture, 0); BelongMagic = belongMagic; BelongCharacter = belongCharacter; MoveDirection = moveDirection; _destroyOnEnd = destroyOnEnd; SetDirection(MoveDirection); _lastUserWorldPosition = belongCharacter.PositionInWorld; _rangeElapsedMilliseconds = belongMagic.RangeTimeInerval; if (BelongMagic.MeteorMove > 0) { _waitMilliSeconds = Globals.TheRandom.Next(1000); var dir = (BelongMagic.MeteorMoveDir > 7) ? Globals.TheRandom.Next(8) : BelongMagic.MeteorMoveDir; var path = new LinkedList <Vector2>(); path.AddFirst(positionInWorld); var tile = Map.ToTilePosition(positionInWorld, false); for (var i = 0; i <= BelongMagic.MeteorMove; i++) { tile = PathFinder.FindNeighborInDirection(tile, dir); path.AddFirst(Map.ToPixelPosition(tile, false)); } SetPath(path); PositionInWorld = path.First.Value; Velocity = belongMagic.Speed * Globals.MagicBasespeed; } return(true); }
public static void Update(GameTime gameTime) { var elapsedMilliseconds = (float)gameTime.ElapsedGameTime.TotalMilliseconds; for (var node = _workList.First; node != null;) { var item = node.Value; var next = node.Next; item.LeftMilliseconds -= elapsedMilliseconds; if (item.LeftMilliseconds <= 0) { AddMagicSprite(item.TheSprite); _workList.Remove(node); } node = next; } for (var node = _magicSprites.First; node != null;) { var sprite = node.Value; var next = node.Next; if (sprite.IsDestroyed) { RemoveMagicSprite(node); } else { sprite.Update(gameTime); } node = next; } for (var node = _solideMagicSprites.First; node != null;) { var sprite = node.Value; var next = node.Next; if (sprite.IsInDestroy || sprite.IsDestroyed) { _solideMagicSprites.Remove(node); } node = next; } for (var node = _effectSprites.First; node != null;) { var sprite = node.Value; var next = node.Next; sprite.Update(gameTime); if (!sprite.IsInPlaying) { _effectSprites.Remove(node); } node = next; } for (var node = _kind19Magics.First; node != null;) { var info = node.Value; var next = node.Next; if (info.LastTilePosition != info.BelongCharacter.TilePosition) { AddFixedPositionMagicSprite(info.BelongCharacter, info.TheMagic, Map.ToPixelPosition(info.LastTilePosition), true); info.LastTilePosition = info.BelongCharacter.TilePosition; } info.KeepMilliseconds -= elapsedMilliseconds; if (info.KeepMilliseconds <= 0) { _kind19Magics.Remove(node); } node = next; } }
//Returned path is in pixel position public static LinkedList <Vector2> FindPathStep(Character finder, Vector2 startTile, Vector2 endTile, int stepCount) { if (finder == null) { return(null); } if (startTile == endTile) { return(null); } if (Globals.TheMap.IsObstacleForCharacter(endTile)) { return(null); } var path = new LinkedList <Vector2>(); var visted = new LinkedList <Vector2>(); var endPositon = Map.ToPixelPosition(endTile); path.AddLast(Map.ToPixelPosition(startTile)); var current = startTile; var maxTry = 100;// For performance while (maxTry-- > 0) { var direction = Utils.GetDirectionIndex(endPositon - Map.ToPixelPosition(current), 8); var neighbors = FindAllNeighbors(current); var removeList = GetObstacleIndexList(neighbors); var index = -1; var list = new int[] { direction, (direction + 1) % 8, (direction + 8 - 1) % 8, (direction + 2) % 8, (direction + 8 - 2) % 8, (direction + 3) % 8, (direction + 8 - 3) % 8, (direction + 4) % 8 }; for (var i = 0; i < 8; i++) { var position = neighbors[list[i]]; if (removeList.Contains(list[i]) || HasObstacle(finder, position) || visted.Contains(position)) { continue; } index = list[i]; break; } if (index == -1) { break; } current = neighbors[index]; path.AddLast(Map.ToPixelPosition(current)); visted.AddLast(current); if (path.Count > stepCount || current == endTile) { break; } } return(path.Count < 2 ? null : path);; }
public static float GetTilePositionCost(Vector2 fromTile, Vector2 toTile) { return(Vector2.Distance(Map.ToPixelPosition(fromTile), Map.ToPixelPosition(toTile))); }