xaguzman / pathfinding

Java pathfinding framework.
Apache License 2.0
97 stars 27 forks source link

Diagonal fixtures #20

Closed undefined-user-ctrl closed 5 years ago

undefined-user-ctrl commented 5 years ago

Hi,

I used the original DIagonalNavigationLayer but i found some issues. I cant tell you specific what it was because it was a some time ago, i would like to share my version, maybe you could use it in your original project or base on it to fix:


package com.riot.pathfinding;

import org.xguzm.pathfinding.PathFinderOptions;
import org.xguzm.pathfinding.grid.GridCell;
import org.xguzm.pathfinding.grid.NavigationGrid;
import org.xguzm.pathfinding.grid.NavigationGridGraphNode;
import org.xguzm.pathfinding.grid.finders.GridFinderOptions;

import java.util.ArrayList;
import java.util.List;

public class DiagonalNavigationGrid<T extends NavigationGridGraphNode> extends NavigationGrid {
    private List neighbors = new ArrayList();

    public DiagonalNavigationGrid(GridCell[][] nodes) {
        super(nodes, false);
    }

    @Override
    public List getNeighbors(NavigationGridGraphNode cell) {
        return super.getNeighbors(cell);
    }

    @Override
    public List getNeighbors(NavigationGridGraphNode node, PathFinderOptions opt) {
        GridFinderOptions options = (GridFinderOptions) opt;
        boolean allowDiagonal = options.allowDiagonal;
        boolean dontCrossCorners = options.dontCrossCorners;
        int yDir = options.isYDown ? -1 : 1;
        int x = node.getX(), y = node.getY();
        neighbors.clear();
        boolean s0 = false, d0 = false, s1 = false, d1 = false,
                s2 = false, d2 = false, s3 = false, d3 = false;

        // up
        if (isWalkable(x, y + yDir)) {
            neighbors.add(nodes[x][y + yDir]);
            s0 = true;
        }
        // right
        if (isWalkable(x + 1, y)) {
            neighbors.add(nodes[x + 1][y]);
            s1 = true;
        }
        // down
        if (isWalkable(x, y - yDir)) {
            neighbors.add(nodes[x][y - yDir]);
            s2 = true;
        }
        // left
        if (isWalkable(x - 1, y)) {
            neighbors.add(nodes[x - 1][y]);
            s3 = true;
        }

        if (!allowDiagonal) {
            return neighbors;
        }

        if (dontCrossCorners) {
            d0 = s3 && s0;
            d1 = s0 && s1;
            d2 = s1 && s2;
            d3 = s2 && s3;
        } else {
            d0 = true;//s3 || s0;
            d1 = true;//s0 || s1;
            d2 = true;//s1 || s2;
            d3 = true;//s2 || s3;
        }

        // up left
        if (d0 && this.isWalkable(x - 1, y + yDir)) {
            neighbors.add(nodes[x - 1][y + yDir]);
        }
        // up right
        if (d1 && this.isWalkable(x + 1, y + yDir)) {
            neighbors.add(nodes[x + 1][y + yDir]);
        }
        // down right
        if (d2 && this.isWalkable(x + 1, y - yDir)) {
            neighbors.add(nodes[x + 1][y - yDir]);
        }
        // down left
        if (d3 && this.isWalkable(x - 1, y - yDir)) {
            neighbors.add(nodes[x - 1][y - yDir]);
        }

        return neighbors;
    }
}

I end up using a new DiagonalNavigationTileMapLayer also, just to reference the above class.

Hope it helps someone. Thanks!

xaguzman commented 5 years ago

Thanks for the contribution, however, if you come to remember what the issue it specifically solved I would really appreciate providing a pull request to integrate it into the project :)

xaguzman commented 5 years ago

Marking this as invalid as it's the wrong channel for the content.

I do however, really appreciate the intention to help. Please throw a PR instead!

undefined-user-ctrl commented 5 years ago

Sorry, i didn't even remember about PR! Will create one soon. Thanks!