Here's an example of using SFML to display a map of nodes and connect them with lines based on an A* pathfinding algorithm in C#:
main.csusing SFML.Graphics;
using SFML.System;
using SFML.Window;
using System;
using System.Collections.Generic;
namespace SFMLPathfinding
{
class Node
{
public Vector2f Position { get; set; }
public List<Node> Neighbors { get; set; }
public float G { get; set; }
public float H { get; set; }
public float F { get { return G + H; } }
public Node CameFrom { get; set; }
public bool IsObstacle { get; set; }
public Node(Vector2f position)
{
Position = position;
Neighbors = new List<Node>();
G = float.MaxValue;
H = float.MaxValue;
CameFrom = null;
IsObstacle = false;
}
}
class Program
{
static int mapSize = 20;
static int nodeSize = 30;
static RenderWindow window;
static List<Node> nodes = new List<Node>();
static List<Node> path = new List<Node>();
static void Main(string[] args)
{
window = new RenderWindow(new VideoMode(mapSize * nodeSize, mapSize * nodeSize), "SFML Pathfinding");
window.Closed += WindowClosed;
// Generate the map with nodes
GenerateNodes();
// Connect the neighboring nodes
ConnectNeighbors();
// Set some random obstacles
SetObstacles();
// Calculate the path between two nodes
CalculatePath(nodes[0], nodes[nodes.Count - 1]);
while (window.IsOpen)
{
window.DispatchEvents();
window.Clear(Color.White);
// Draw the nodes and connections
DrawNodes();
DrawConnections();
// Draw the path
DrawPath();
window.Display();
}
}
static void GenerateNodes()
{
for (int y = 0; y < mapSize; y++)
{
for (int x = 0; x < mapSize; x++)
{
Vector2f position = new Vector2f(x * nodeSize, y * nodeSize);
Node node = new Node(position);
nodes.Add(node);
}
}
}
static void ConnectNeighbors()
{
foreach (Node node in nodes)
{
int x = (int)(node.Position.X / nodeSize);
int y = (int)(node.Position.Y / nodeSize);
for (int ny = y - 1; ny <= y + 1; ny++)
{
for (int nx = x - 1; nx <= x + 1; nx++)
{
if (nx >= 0 && ny >= 0 && nx < mapSize && ny < mapSize && (nx != x || ny != y))
{
Node neighbor = nodes[ny * mapSize + nx];
node.Neighbors.Add(neighbor);
}
}
}
}
}
static void SetObstacles()
{
Random random = new Random();
for (int i = 0; i < nodes.Count / 3; i++)
{
int index = random.Next(0, nodes.Count);
nodes[index].IsObstacle = true;
}
}
static void CalculatePath(Node startNode, Node goalNode)
{
List<Node> openSet = new List<Node>();
List<Node> closedSet = new List<Node>();
startNode.G = 0;
startNode.H = Heuristic(startNode, goalNode);
openSet.Add(startNode);
while (openSet.Count > 0)
{
Node current = GetLowestF(openSet);
if (current == goalNode)
{
// Found the path
path.Clear();
Node node = current;
while (node != null)
{
path.Add(node);
node = node.CameFrom;
}
path.Reverse();
return;
}
openSet.Remove(current);
closedSet.Add(current);
foreach (Node neighbor in current.Neighbors)
{
if (closedSet.Contains(neighbor) || neighbor.IsObstacle)
{
// Ignore this neighbor
continue;
}
float tentativeGScore = current.G + Distance(current, neighbor);
if (!openSet.Contains(neighbor))
{
openSet.Add(neighbor);
}
else if (tentativeGScore >= neighbor.G)
{
// This path is worse than the previous path
continue;
}
neighbor.CameFrom = current;
neighbor.G = tentativeGScore;
neighbor.H = Heuristic(neighbor, goalNode);
}
}
}
static Node GetLowestF(List<Node> nodes)
{
Node lowest = nodes[0];
foreach (Node node in nodes)
{
if (node.F < lowest.F)
{
lowest = node;
}
}
return lowest;
}
static float Distance(Node node1, Node node2)
{
return (float)Math.Sqrt(Math.Pow(node1.Position.X - node2.Position.X, 2) + Math.Pow(node1.Position.Y - node2.Position.Y, 2));
}
static float Heuristic(Node node1, Node node2)
{
// Manhattan distance
return Math.Abs(node1.Position.X - node2.Position.X) + Math.Abs(node1.Position.Y - node2.Position.Y);
}
static void DrawNodes()
{
foreach (Node node in nodes)
{
CircleShape circle = new CircleShape(nodeSize / 2);
circle.Origin = new Vector2f(nodeSize / 2, nodeSize / 2);
circle.Position = node.Position;
if (node.IsObstacle)
{
circle.FillColor = new Color(139, 139, 139);
}
else
{
circle.FillColor = new Color(221, 221, 221);
}
window.Draw(circle);
}
}
static void DrawConnections()
{
foreach (Node node in nodes)
{
foreach (Node neighbor in node.Neighbors)
{
if (!node.IsObstacle && !neighbor.IsObstacle)
{
VertexArray line = new VertexArray(PrimitiveType.Lines, 2);
line[0] = new Vertex(node.Position, Color.Black);
line[1] = new Vertex(neighbor.Position, Color.Black);
window.Draw(line);
}
}
}
}
static void DrawPath()
{
VertexArray pathLine = new VertexArray(PrimitiveType.LinesStrip, (uint)path.Count);
for (int i = 0; i < path.Count; i++)
{
pathLine[(uint)i] = new Vertex(path[i].Position, Color.Red);
}
window.Draw(pathLine);
}
private static void WindowClosed(object sender, EventArgs e)
{
RenderWindow window = (RenderWindow)sender;
window.Close();
Environment.Exit(0);
}
}
}
7647 chars256 lines
This code generates a map of nodes, connects their neighboring nodes, and calculates a path between the start and goal nodes. It also includes random obstacles and displays the resulting path using SFML.
gistlibby LogSnag