0

我正在开发一个使用网格系统的游戏(想想棋盘)。棋盘上的每个图块都有一个位置(行/列)。还有一个方向的概念(N,E,S,W,NE,SE,NW,SW)。

给定两个位置,我正在计算 3 个方向的东西:

  • 方向(N、E、S、W、NE、SW、NW、SW、NONE 或 null。Null 是指瓦片没有在一个方向上完全对齐)。
  • 大方向(如果不是特定方向之一,则属于 NE、SE、NW、SW 大方向)。
  • 最近的方向(如果有平局,则为空)。

例如, (0, 0) -> (4, 3) 有:

  • 零方向
  • SE的总体方向
  • SE最近的方向

和 (0, 0) -> (4, 1) 有:

  • 零方向
  • SE的总体方向
  • S的最近方向

该代码有效,但非常难看。我确信必须有一种更简洁的算法来设置值,并且重复次数要少得多。关于减少重复代码的方法有什么想法吗?

public final class Dimension
{
    private final int rowDistance;
    private final int columnDistance;
    private final Direction direction;
    private final Direction generalDirection;
    private final Direction closestDirection;

    public Dimension(final Location locationA,
                     final Location locationB)
    {
        if(locationA == null)
        {
            throw new IllegalArgumentException("locationA cannot be null");
        }

        if(locationB == null)
        {
            throw new IllegalArgumentException("locationB cannot be null");
        }

        rowDistance    = locationB.getRow()    - locationA.getRow();
        columnDistance = locationB.getColumn() - locationA.getColumn();

        // not moving at all
        if(rowDistance == 0 && columnDistance == 0)
        {
            direction        = Direction.NONE;
            generalDirection = Direction.NONE;
            closestDirection = Direction.NONE;
        }
        else
        {
            final int absoluteDifference;

            absoluteDifference = Math.abs(Math.abs(rowDistance) - Math.abs(columnDistance));

            // North Westish
            if(rowDistance <= 0 && columnDistance <= 0)
            {
                final int north;
                final int west;
                final int northWest;

                if(absoluteDifference == 0)
                {
                    direction        = Direction.NORTH_WEST;
                    generalDirection = Direction.NORTH_WEST;
                }
                else if(rowDistance == 0)
                {
                    direction        = Direction.WEST;
                    generalDirection = Direction.WEST;
                }
                else if(columnDistance == 0)
                {
                    direction        = Direction.NORTH;
                    generalDirection = Direction.NORTH;
                }
                else
                {
                    direction        = null;
                    generalDirection = Direction.NORTH_WEST;
                }

                north     = Math.abs(columnDistance);
                west      = Math.abs(rowDistance);
                northWest = Math.abs(
                               Math.abs(Math.max(rowDistance, columnDistance)) - 
                               Math.abs(Math.min(rowDistance, columnDistance)));

                if(northWest < west && northWest < north)
                {
                    closestDirection = Direction.NORTH_WEST;
                }
                else if(west < northWest && west < north)
                {
                    closestDirection = Direction.WEST;
                }
                else if(north < northWest && north < west)
                {
                    closestDirection = Direction.NORTH;
                }
                else
                {
                    closestDirection = null;
                }
            }
            // North Eastish
            else if(rowDistance <= 0 && columnDistance >= 0)
            {
                final int north;
                final int east;
                final int northEast;

                if(absoluteDifference == 0)
                {
                    direction        = Direction.NORTH_EAST;
                    generalDirection = Direction.NORTH_EAST;
                }
                else if(rowDistance == 0)
                {
                    direction        = Direction.EAST;
                    generalDirection = Direction.EAST;
                }
                else if(columnDistance == 0)
                {
                    direction        = Direction.NORTH;
                    generalDirection = Direction.NORTH;
                }
                else
                {
                    direction        = null;
                    generalDirection = Direction.NORTH_EAST;
                }

                north     = Math.abs(columnDistance);
                east      = Math.abs(rowDistance);
                northEast = Math.abs(
                               Math.abs(Math.max(rowDistance, columnDistance)) -             
                               Math.abs(Math.min(rowDistance, columnDistance)));

                if(northEast < east && northEast < north)
                {
                    closestDirection = Direction.NORTH_EAST;
                }
                else if(east < northEast && east < north)
                {
                    closestDirection = Direction.EAST;
                }
                else if(north < northEast && north < east)
                {
                    closestDirection = Direction.NORTH;
                }
                else
                {
                    closestDirection = null;
                }
            }
            // South Westish
            else if(rowDistance >= 0 && columnDistance <= 0)
            {
                final int south;
                final int west;
                final int southWest;

                if(absoluteDifference == 0)
                {
                    direction        = Direction.SOUTH_WEST;
                    generalDirection = Direction.SOUTH_WEST;
                }
                else if(rowDistance == 0)
                {
                    direction        = Direction.WEST;
                    generalDirection = Direction.WEST;
                }
                else if(columnDistance == 0)
                {
                    direction        = Direction.SOUTH;
                    generalDirection = Direction.SOUTH;
                }
                else
                {
                    direction        = null;
                    generalDirection = Direction.SOUTH_WEST;
                }

                south     = Math.abs(columnDistance);
                west      = Math.abs(rowDistance);
                southWest = Math.abs(
                               Math.abs(Math.max(rowDistance, columnDistance)) - 
                               Math.abs(Math.min(rowDistance, columnDistance)));

                if(southWest < west && southWest < south)
                {
                    closestDirection = Direction.SOUTH_WEST;
                }
                else if(west < southWest && west < south)
                {
                    closestDirection = Direction.WEST;
                }
                else if(south < southWest && south < west)
                {
                    closestDirection = Direction.SOUTH;
                }
                else
                {
                    closestDirection = null;
                }
            }
            // South Eastish
            else
            {
                final int south;
                final int east;
                final int southEast;

                if(absoluteDifference == 0)
                {
                    direction        = Direction.SOUTH_EAST;
                    generalDirection = Direction.SOUTH_EAST;
                }
                else if(rowDistance == 0)
                {
                    direction        = Direction.EAST;
                    generalDirection = Direction.EAST;
                }
                else if(columnDistance == 0)
                {
                    direction        = Direction.SOUTH;
                    generalDirection = Direction.SOUTH;
                }
                else
                {
                    direction = null;
                    generalDirection = Direction.SOUTH_EAST;                    
                }

                south     = Math.abs(columnDistance);
                east      = Math.abs(rowDistance);
                southEast = Math.abs(
                              Math.abs(Math.max(rowDistance, columnDistance)) - 
                              Math.abs(Math.min(rowDistance, columnDistance)));

                if(southEast < east && southEast < south)
                {
                    closestDirection = Direction.SOUTH_EAST;
                }
                else if(east < southEast && east < south)
                {
                    closestDirection = Direction.EAST;
                }
                else if(south < southEast && south < east)
                {
                    closestDirection = Direction.SOUTH;
                }
                else
                {
                    closestDirection = null;
                }
            }
        }
    }

    public int getRowDistance()
    {
        return (rowDistance);
    }

    public int getColumnDistance()
    {
        return (columnDistance);
    }

    public Direction getDirection()
    {
        return (direction);
    }

    public Direction getGeneralDirection()
    {        
        return (generalDirection);
    }

    public Direction getClosestDirection()
    {        
        return (closestDirection);
    }
}
4

1 回答 1

1

我会像你一样计算距离,然后我会将正交距离传递给 Math.Atan2 以计算可以缩放 (int)Math.Round(H * 4 / Math.PI) 到 0- 范围内的航向 H 7 作为一个散列,从 N 开始通过罗盘点顺时针计数,假设您顺时针枚举,您可以直接将其投射到您的枚举中。

于 2012-10-31T05:09:53.103 回答