public BPathNode(int x, int y, bool obstructed, BPathNode parent, bool visited) { X = x; Y = y; Obstructed = obstructed; Parent = parent; Visited = visited; Neighbours = new List <BPathNode>(); Destination = false; }
public BCharacter(Vector2 position, BTexture spriteSheet, RectangleF spriteBox, BMovementType movementType) : base(position, spriteSheet, spriteBox) { this.movementType = movementType; positionGoto = position; velocity = Vector2.Zero; currentState = BEntityState.Idle; maxMovementSpeed = 20.0f; maxHealth = 200; currentHealth = maxHealth; path = null; pathNode = null; }
public BCharacter(Vector2 position, BTexture spriteSheet) : base(position, spriteSheet) { movementType = BMovementType.MoveToPosition; positionGoto = position; velocity = Vector2.Zero; currentState = BEntityState.Idle; maxMovementSpeed = 20.0f; maxHealth = 200; currentHealth = maxHealth; path = null; pathNode = null; }
public BNavigationGrid(int x, int y, int levelWidth, int levelHeight, int levelTileSize, int tileSizeX, int tileSizeY) { this.x = x; this.y = y; this.width = (levelWidth * levelTileSize) / tileSizeX; this.height = (levelHeight * levelTileSize) / tileSizeY; this.tileSizeX = tileSizeX; this.tileSizeY = tileSizeY; this.destNode = null; this.startNode = null; // Initiate the nodes this.grid = new BPathNode[width, height]; for (int x2 = 0; x2 < width; x2++) { for (int y2 = 0; y2 < height; y2++) { grid[x2, y2] = new BPathNode(x2, y2, false, null, false); } } // Set up neighbours for (int x2 = 0; x2 < width; x2++) { for (int y2 = 0; y2 < height; y2++) { grid[x2, y2].Neighbours.Clear(); if (x2 + 1 < width) { grid[x2, y2].Neighbours.Add(grid[x2 + 1, y2]); } if (y2 + 1 < height) { grid[x2, y2].Neighbours.Add(grid[x2, y2 + 1]); } if (x2 - 1 >= 0) { grid[x2, y2].Neighbours.Add(grid[x2 - 1, y2]); } if (y2 - 1 >= 0) { grid[x2, y2].Neighbours.Add(grid[x2, y2 - 1]); } } } }
public override void Draw() { Camera.ApplyTransform(); base.Draw(); for (int x = 0; x < Level.Width; x++) { for (int y = 0; y < Level.Height; y++) { RectangleF source = Level[x, y].TexturePosition; BGraphics.Draw(Textures[0], new Vector2(x * AppInfo.GRIDSIZE, y * AppInfo.GRIDSIZE), new Vector2((float)AppInfo.GRIDSIZE / AppInfo.TILESIZE), Color.Transparent, Vector2.Zero, source); } } List <BEntity> renderOrder = new List <BEntity>(); renderOrder.AddRange(Level.Entities); if (Player != null) { renderOrder.Add(Player); } renderOrder = renderOrder.OrderBy(x => x.GroundLevel).ToList <BEntity>(); foreach (BEntity entity in renderOrder) { if (entity == null) { return; } entity.Draw(); } if (AppSettings.SETTING_NAVIGATION_DEBUG) { for (int x = 0; x < NavMesh.Width; x++) { for (int y = 0; y < NavMesh.Height; y++) { var color = Color.Green; if (NavMesh[x, y].Obstructed) { color = Color.Red; } else if (!NavMesh[x, y].Visited) { color = Color.Black; } BGraphics.DrawRec(new Vector2(x * NavMesh.TileSizeX, y * NavMesh.TileSizeY), new RectangleF(x * NavMesh.TileSizeX, y * NavMesh.TileSizeY, NavMesh.TileSizeX, NavMesh.TileSizeY), color); } } } if (AppSettings.SETTING_PATHFINDING_DEBUG) { if (NavMesh.DestNode != null) { BPathNode pathNode = NavMesh.DestNode; BGraphics.DrawRec(new Vector2(pathNode.X * NavMesh.TileSizeX, pathNode.Y * NavMesh.TileSizeY), new RectangleF(pathNode.X * NavMesh.TileSizeX, pathNode.Y * NavMesh.TileSizeY, NavMesh.TileSizeX, NavMesh.TileSizeY), Color.Orange); while (pathNode.Parent != null) { BGraphics.DrawRec(new Vector2(pathNode.X * NavMesh.TileSizeX, pathNode.Y * NavMesh.TileSizeY), new RectangleF(pathNode.X * NavMesh.TileSizeX, pathNode.Y * NavMesh.TileSizeY, NavMesh.TileSizeX, NavMesh.TileSizeY), Color.Yellow); pathNode = pathNode.Parent; } } } }
public void HandleMovement(double delta) { if (this.movementType == BMovementType.MoveToPosition) { if (positionGoto.Y - this.position.Y >= 0.1f) { velocity.Y = Math.Min(maxMovementSpeed, (positionGoto.Y - this.position.Y)); } else if (this.position.Y - positionGoto.Y >= 0.1f) { velocity.Y = Math.Max(-maxMovementSpeed, -(this.position.Y - positionGoto.Y)); } else { velocity.Y = 0.0f; } if (positionGoto.X - this.position.X >= 0.1f) { velocity.X = Math.Min(maxMovementSpeed, (positionGoto.X - this.position.X)); } else if (this.position.X - positionGoto.X >= 0.1f) { velocity.X = Math.Max(-maxMovementSpeed, -(this.position.X - positionGoto.X)); } else { velocity.X = 0.0f; } } else if (this.movementType == BMovementType.FollowPath) { if (path != null) { if (pathNode == null && path.DestNode.Parent != null) { pathNode = path.DestNode.Parent; } if (pathNode.Parent != null) { Vector2 nodeVec = new Vector2((pathNode.X * path.TileSizeX) + (path.TileSizeX / 2), (pathNode.Y * path.TileSizeY) + (path.TileSizeY / 2)); if (Vector2.Distance(nodeVec, position) > 10.0f) { Vector2 dir = new Vector2(nodeVec.X, nodeVec.Y) - position; MoveInDirection(dir); } else { pathNode = pathNode.Parent; path.DestNode = pathNode; } } else { velocity = Vector2.Zero; path.DestNode = null; path.StartNode = null; } } } if (velocity == Vector2.Zero) { currentState = BEntityState.Idle; } if (velocity.Y > 0f) { if (velocity.X > 0f) { if (velocity.X > velocity.Y) { currentState = BEntityState.MovingR; } else if (velocity.X < velocity.Y) { currentState = BEntityState.MovingD; } } if (velocity.X < 0f) { if (-velocity.X > velocity.Y) { currentState = BEntityState.MovingL; } else if (-velocity.X < velocity.Y) { currentState = BEntityState.MovingD; } } } else if (velocity.Y < 0f) { if (velocity.X > 0f) { if (velocity.X > -velocity.Y) { currentState = BEntityState.MovingR; } else if (velocity.X < -velocity.Y) { currentState = BEntityState.MovingU; } } if (velocity.X < 0f) { if (-velocity.X > -velocity.Y) { currentState = BEntityState.MovingL; } else if (-velocity.X < -velocity.Y) { currentState = BEntityState.MovingU; } } } else { if (velocity.X > 0f) { currentState = BEntityState.MovingR; } if (velocity.X < 0f) { currentState = BEntityState.MovingL; } } velocity = new Vector2(Maths.Clamp(velocity.X, -MaxMovementSpeed, MaxMovementSpeed), Maths.Clamp(velocity.Y, -MaxMovementSpeed, MaxMovementSpeed)); this.position += (velocity * (float)delta); }
private float DistanceBetweenNodes(BPathNode node1, BPathNode node2) { return(Vector2.Distance(new Vector2(node1.X, node1.Y), new Vector2(node2.X, node2.Y))); }
public void FindPathTo(Vector2 start, Vector2 destination) { if (start == destination) { return; } for (int x2 = 0; x2 < width; x2++) { for (int y2 = 0; y2 < height; y2++) { grid[x2, y2].GlobalGoal = float.MaxValue; grid[x2, y2].LocalGoal = float.MaxValue; grid[x2, y2].Parent = null; grid[x2, y2].Visited = false; grid[x2, y2].Destination = false; } } int startX = (int)(destination.X / tileSizeX); int startY = (int)(destination.Y / tileSizeY); int destX = (int)(start.X / tileSizeX); int destY = (int)(start.Y / tileSizeY); if (startX >= 0 && startX < width && destX >= 0 && destX < width && startY >= 0 && startY < height && destY >= 0 && destY < height) { destNode = grid[destX, destY]; destNode.Destination = true; startNode = grid[startX, startY]; startNode.LocalGoal = 0.0f; startNode.GlobalGoal = DistanceBetweenNodes(startNode, destNode); BPathNode nodeCurrent = startNode; nodeCurrent = startNode; List <BPathNode> notTestedNodes = new List <BPathNode>(); notTestedNodes.Add(startNode); while (notTestedNodes.Count != 0) { notTestedNodes = notTestedNodes.OrderBy(j => j.GlobalGoal).ToList <BPathNode>(); while (notTestedNodes.Count != 0 && notTestedNodes[0].Visited) { notTestedNodes.RemoveAt(0); } if (notTestedNodes.Count == 0) { break; } nodeCurrent = notTestedNodes[0]; nodeCurrent.Visited = true; foreach (var neighbour in nodeCurrent.Neighbours) { if (!neighbour.Obstructed && !neighbour.Visited) { notTestedNodes.Add(neighbour); } float possiblyLowerGoal = nodeCurrent.LocalGoal + DistanceBetweenNodes(nodeCurrent, neighbour); if (possiblyLowerGoal < neighbour.LocalGoal) { neighbour.Parent = nodeCurrent; neighbour.LocalGoal = possiblyLowerGoal; neighbour.GlobalGoal = neighbour.LocalGoal + DistanceBetweenNodes(neighbour, destNode); } } } } }