How to code a pathfinding player in godot using A*? - path-finding

Iam nooby in godot, I have to use A* to traslate the player to the goal position, but I do not know how to start, pls help!! basically I have just 2 tiles in the tilemap, 1 of them is allowed to pass over it, I have to extract I guess the allowed tile and calculate the distance between the position player with the position goal, getting the real distance and then check cell per cell which has the lowest cost, but I do not know how to do that :c
func get_player_init_pos():
var pos = map_to_world(Vector2(54,1))pos.y += half_cell_size.y
return pos
func is_tile_vacant(pos, direction):
var curr_tile = world_to_map(pos)
var next_tile = get_cellv(curr_tile + direction)
var next_tile_pos = Vector2()
if(next_tile == 0):
next_tile_pos = map_to_world(curr_tile + direction)
else:next_tile_pos = pos
return next_tile_pos
I have this, the first part of the code is to locate the player in the map and the second is for check the tile walls in the map

You could roll your own path finding algorithm. However, there is little point in doing so, since Godot has a AStar class you can use. However, you probably don't need to use that either, because Godot has a navigation system. And that is what I'm going to suggest you to use.
First of all, you can specify both navigation and collision polygons on your tiles. You need to have the navigation polygons. Go ahead and do them.
Second you want to have a Navigation2D in the scene tree and have your TileMap as a child.
And third, you can ask the Navigation2D for a path with get_simple_path, you pass the start and end positions as arguments and you get an array of points that make up the path.
Since you mention A*, I'll briefly explain using the AStar too anyway.
First, you need to add the cells with add_point. It requires ids. It is a good idea to be clever with the ids so you can compute the id for a given position. For example x * width + y if you know the size.
So you can iterate over the tiles in your TileMap and call add_point for each one (You don't need to add cell that are not passable).
Then you need to specify the connections with connect_points (it takes the ids of the points as parameters).
And finally you can call get_point_path passing the start and end ids. Again it gives you a array of points.

Related

Calculate all end points on a graph given n stamina?

I am attempting to create a pathfinding algorithm for a game. Basically, after the player rolls a number, I need to determine all possible locations that the player can end up on a grid. The player cannot move directly backwards after a given step, and the player can only move one grid square per step.
The problem is, right now I am attempting to brute force the solution by recursively navigating along the graph and manually checking each valid move.
Pseudocode:
// Recursive function for navigating one step at a time.
function navigate($stamina, $coords, $coords_previous)
{
// If the movement stamina has not been spent.
if ($stamina != 0)
{
// Note: there may be less than four neighboring
// cells in a given location due to obstacles.
foreach ($neighboring_cells as $coords_neighboring)
{
// If the coordinates of the neighbor are not the same as the
// coordinates of the previous move (we can't move backwards)
if ($coords_neighboring != $coords_previous)
{
$stamina--;
// Recurse.
navigate($stamina, $coords_neighboring, $coords);
}
}
}
else
{
// No more stamina.
// Add $coords to our array of endpoints.
}
}
This works for small rolls (low $stamina values). However, as $stamina increases, this methodology starts to become super redundant. This is due to the fact that the player can move in circles over and over again, exponentially increasing the number of potential endpoints.
My question is, what can be done to decrease redundancy in the above function?
Define a state as a combination of a grid position and a facing (i.e., the direction the player moved in to get there). This is useful because we can define successors of a given state: in particular, those at adjacent grid positions (with appropriate facings) other than the one the player just came from.
Then compute the set of states reachable in n steps. For n=0, this is just the player's initial position (with a special "no facing" value if the first move can be in any direction). To compute it for n+1, generate all valid moves from each of the states in the previous set, discarding any duplicates. When you reach the set for $stamina steps, just discard the facings (and any duplicate positions).
In terms of graph algorithms
This is similar to a breadth-first search on a graph whose vertices are the states and whose edges connect a state to its successor states. However, here we don't disregard new (longer) paths to a state, since some positions might be reachable (in exactly $stamina steps!) only via looping back. One could also include the remaining stamina in the state (and define no edges away from a state with 0 moves left); then you would perform a normal graph search and collect all the leaves.
In either case these would probably be implicit graphs, but the algorithm is clearer implemented directly rather than in terms of a graph.

GKObstacleGraph How to Find Closest Valid point?

In a scenario where user wants to navigate via mouse or touch to some are of the map that is not passable. When sending the point to GKObstacleGRpah FindPath it just returns an empty array.
I want the unit to go to closest (or close enough) passable point.
What would be an appropriate way to find a closest valid point in GKObstacleGraph.
I understand that I can get the GKObstacle so I can enumerate it's vertices, and I know my unit's position...
But well... what is the next step ?
NOTE: I am not using GKAgengts.
Here was my thinking as I worked through this problem. There may be an easier answer, but I haven’t found it.
1. Figure out if a point is valid or not.
To do this, I actually have a CGPath representation of each obstacle. I export paths from PhysicsEditor and then load them in through a custom script that converts them to CGPath. I always store that CGPath along with the GKObstacle I created from the path. Finally, I can call CGPathContainsPoint to determine the the obstacle contains the point. If true, I know the point is invalid.
2. Once the point is invalid, find out which obstacle was clicked.
With my approach in #1, I already have a handle on the CGPath and obstacle it belongs to.
3. Find closest vertex
Now that I know the obstacle, find the vertex closest to the unit that is moving. I wouldn’t find the closet vertex to the point clicked because that could be around a corner. Instead, figure out the vector between the desired position and the unit. Then, draw an invisible line from the desired position through the vertex. I used this equation to find out where the lines would cross.
// http://stackoverflow.com/questions/1811549/perpendicular-on-a-line-from-a-given-point
let k = ((end.y - start.y) * (hitPoint.x - start.x) - (end.x - start.x) * (hitPoint.y - start.y)) / ((end.y - start.y) * (end.y - start.y) + (end.x - start.x) * (end.x - start.x))
let x4 = hitPoint.x - k * (end.y - start.y)
let y4 = hitPoint.y + k * (end.x - start.x)
let ret = float2(x: x4, y: y4)
4. Offset intersection by unit size towards moving unit
Knowing where the paths intersect along with the vector towards the unit, we can just move to intersection point + (the vector * unit size).
5. Edge cases
This gets tricky when you have two obstacles touching each other, or if you have very large obstacles. The user may think they are moving to the far side of the map, but this script will follow back to the closet valid point which could be nearby. Because of that, I scrapped all of the code and I just don’t allow you to move to invalid positions. A red X and a buzz sound happens prompting the user to select a new, valid position on the map.
6. DemoBots
I could be wrong, but I vaguely recall DemoBots from Apple having similar logic — they may be a good reference too.
7. Debug Layer
This took forever for me to get a proof of concept together. I’d highly recommend drawing lines on a debug layer to verify your logic.

Constrained (Delaunay) Triangulation

For a university project I need to implement a computer graphics paper that has been relased a couple of years ago. At one point, I need to triangulate the results I get from my simulation. I guess its easier to explain what I need looking at a picture contained within the paper:
Let's say I already have got all the information it takes to reconstruct the contour lines that you can see in the second thumbnail. Using those I need to do some triangulation using those siluettes as constrains. I have searched the internet for triangulation libraries like CGAL, VTK, Triangle, Triangle++, ... but I always ended up throwing my hands up in horror. I am not a good programmer and it seems impossible to me to get into one of those APIs before the deadline of this project passes.
I would appreciate any kind of help like code snipplets, tips, etc...
I know that the algorithms need segments (pairs of points) as input, so let's say I have got one std::vector containing all pairs of points defining the siluette as well as the left and right side of the rectangle.
Can you somehow give me a code snipplet for i.e. CGAL that I could use for my purpose? First of all I just want to achieve the state of the third thumbnail. Lateron I will have to do some displacement within the "cracks" and finally write the information into a VBO for OpenGL rendering.
I have started working it out with CGAL. One simple problem still drives me crazy:
It is possible to attach informations (like ints) to points before adding them up to the triangulator object. I do this since I need on the one hand an int-flag that I use lateron to define my texture coordinates and on the other hand an index which I use so that I can create a indexed VBO.
http://doc.cgal.org/latest/Triangulation_2/Triangulation_2_2info_insert_with_pair_iterator_2_8cpp-example.html
But instead of points I only want to insert constraint-edges. If I insert both CGAL returns strange results since points have been fed into two times (once as point and once as point of a constrained edge).
http://doc.cgal.org/latest/Triangulation_2/Triangulation_2_2constrained_8cpp-example.html
Is it possible to connect in the same way as with points information to "Constraints" so that I can only use this function cdt.insert_constraint( Point(j,0), Point(j,6)); before I iterate over the resulting faces?
Lateron when I loop over the triangles I need some way to access the int-flags that I defined before. Like this but not on acutal points but the "ends" defined by the constraint edges:
for(CDT::Finite_faces_iterator fit = m_cdt.finite_faces_begin(); fit != m_cdt.finite_faces_end(); ++fit, ++k) {
int j = k*3;
for(int i=0; i < 3; i++) {
indices[j+i] = fit->vertex(i)->info().first;
}
}

How to Find global position of objects in a rotating scene THREE.JS

I am working on a 3D mesh manipulator using this : http://leapmotion.com. So far, I have been able manipulate the points just fine, by 'grabbing' and moving them, however I now want to be able to rotate the mesh and work on the opposite face. What I have done is add an extra object that is called 'rotatable' as Shown below:
scene=new THREE.Scene();
camera = new THREE.PerspectiveCamera(70,window.innerWidth/window.innerHeight,1,8000)
renderer=new THREE.WebGLRenderer( { clearColor: 0x000000, clearAlpha: 1, maxLights:5 } )
//This is the 'Mesh Scene'
rotatable = new THREE.Object3D()
scene.add(rotatable)
//Mesh we are altering
var material = new THREE.MeshNormalMaterial()
material.side=2
var geom = new THREE.SphereGeometry(200,10,10);
var sphere = new THREE.Mesh(geom, material)
rotatable.add(sphere)
I am then trying to change the vertices of this sphere, but to do so I need to do a 'collision test' in order to see if the vertex is being 'grabbed' This involves check the vertex position and see if it coincides with one of your finger position (psuedoCode below)
if(finger.x == vertex.x && finger.y == vertex.y && finger.z == vertex.z){
vertex.grabbed = true
}
This works fine when the rotatable's rotation is zero, however when it starts to rotate, the collision test will still be testing for the unrotated vertex position (which makes sense). My question is how to find the position of the vertex in its 'scene / global' position. The only way I can think of doing this so far is to calculate the rotation of the 'rotatable' and use this vector to calculate the new vertex position.
I know nothing about math, so this may not be the way to go, and even if it is I will have to struggle through it so hard that I won't ever know if I'm just doing the math incorrectly, or this isn't the way I should go about calculating it. Obviously I'm willing to go through this work, but just want to make sure this is the way to do it, rather then an other simpler method.
If there are any other questions about the code, please let me know, and Thanks in advance for your time!
Isaac
To get the world position of a vertex specified in local coordinates, apply the object's world transform to the vertex like so:
vertex.applyMatrix4( object.matrixWorld );
(I am not familiar with leapmotion, so hopefully it does not impact this answer.)
Tip: maxLights is no longer required. And it is best to avoid material.side = 2. Use material.side = THREE.DoubleSide instead.
You can find the constants here: https://github.com/mrdoob/three.js/blob/master/src/Three.js
three.js r.55

Google Maps API v3 Polylines not drawing

App works this way:
User enters a starting location and a distance. User can choose to draw circles, or lines over the roads. Circles work fine. Lines used to work.
When Lines, the code finds the lat/long of the starting location, then for the points N, S, E, W of the origin at the distance set by the user (say, 100km). Starting with the N destination, the code calls google.maps.DirectionsService() to get directions from the origin to N. This returns an array of lat/longs in the the route.overview_path.
NOTE: I COULD use the directionsRenderer() to draw the route, BUT, the distance drawn would be greater than the distance set by the user. Drawing the entire route from the origin to the point N might be 124km over the roads, and I just want to draw 100km.
Instead, I step through the route.overview_path[] array, checking the distance between that point and the point of origin, adding each point to a new array. When the distance is greater than the dist set by the user, I stop, pop off the last element, then create a new Polyline based on this 2nd, smaller array.
I've spent the entire day in Chrome's developer mode walking through the javascript, setting breakpoints, watching locals, etc. The array of points passed in google.maps.Polyline({}) is a good array of unique points. I just cannot figure out why they aren't rendering.
Ultimately, the code used to draw 4 lines starting at the point of origin, one heading North, one heading East, South, West. etc....
The code is here: http://whosquick.com/RunViz.html
Thank you for your attention.
Nevermind. Solved it.
var objGeo = new LatLon(Geo.parseDMS(myroute.overview_path[0].Pa), Geo.parseDMS(myroute.overview_path[0].Qa));
I had inadvertently switched Pa with Qa.

Resources