簡體   English   中英

計算半徑的二維坐標(對於基於圖塊的游戲)

[英]Calculate 2d coordinates in radius (for a tile based game)

我搜索了一段時間,無法找到滿意的答案。

目前,我有一個瓷磚列表(代表瓷磚ID的int數組),寬度和高度(以瓷磚為單位)的列表。 渲染時,所有圖塊均正確放置,依此類推。但是我的真正問題是,我無法找出一種算法,無法從內向外計算給定半徑(相對於另一個圖塊)內的圖塊。 我計划將其用於照明計算。 這就是為什么我需要從內到外(漸變)進行計算。 我不能在x和y上使用+和-進行靜態計算,因為我計划使用可變的半徑大小。 有人知道這樣做的好方法嗎?

編輯:“從內而外”是指照明的布局方式,靠近光源的照明應該比遠離照明的照明更強烈。 使用以下ASCII內容,我打算直觀地顯示此內容:

0  0  0  0  0  0  0
0  0 --------- 0  0
0  |  *  +  *  |  0
0  |  +  x  +  |  0
0  |  *  +  *  |  0
0  0 --------- 0  0
0  0  0  0  0  0  0

提前致謝 :)

當然,關於如何實現這一點的細節,有許多不同的選擇。 您沒有確切說明如何表示“平鋪”(例如,關於界面)。 但這是一種方法,也許已經有用:

想法是將圖塊的坐標存儲為Point對象的列表。 (可以將這些點轉換為一維索引,但應完全獨立於實際問題)。

這些點是通過沿着所討論區域的“邊緣”走來計算的:

  • 從右下角開始,向上( dx=0, dy=-1
  • 從右上角開始,向左移動( dx=-1, dy=0
  • 從左上角開始,向下( dx=0, dy=1
  • 從左下角開始,向右( dx=1, dy=0

將所有這些點放到一個列表中,此列表隨后包含所有以逆時針方向與中心點具有一定曼哈頓距離的點。

import java.awt.Point;
import java.util.ArrayList;
import java.util.List;

public class TileDistances
{
    public static void main(String[] args)
    {
        int sizeX = 11;
        int sizeY = 11;
        int centerX = 5;
        int centerY = 5;

        for (int radius=1; radius<5; radius++)
        {
            System.out.println(
                "Radius "+radius+" around "+centerX+","+centerY);
            List<Point> points = coordinates(centerX, centerY, radius);
            char c = (char)('0'+radius);
            System.out.println(createString(points, sizeX, sizeY, c));
        }
    }

    private static String createString(
        List<Point> points, int sizeX, int sizeY, char c)
    {
        StringBuffer sb = new StringBuffer();
        for (int y=0; y<sizeY; y++)
        {
            for (int x=0; x<sizeX; x++)
            {
                Point p = new Point(x,y);
                if (points.contains(p))
                {
                    sb.append(c);
                }
                else
                {
                    sb.append(".");
                }
            }
            sb.append("\n");
        }
        return sb.toString();
    }

    private static List<Point> coordinates(
        int cx, int cy, int r)
    {
        List<Point> coordinates = new ArrayList<Point>();
        int steps = r + r;
        addAll(cx + r, cy + r,  0, -1, steps, coordinates);
        addAll(cx + r, cy - r, -1,  0, steps, coordinates);
        addAll(cx - r, cy - r,  0,  1, steps, coordinates);
        addAll(cx - r, cy + r,  1,  0, steps, coordinates);
        return coordinates;
    }

    private static void addAll(
        int x0, int y0, int dx, int dy, int steps,
        List<Point> coordinates)
    {
        int x = x0;
        int y = y0;
        for (int i=0; i<steps; i++)
        {
            coordinates.add(new Point(x,y));
            x += dx;
            y += dy;
        }
    }
}

在此示例中,將打印半徑1至4,例如:

Radius 3 around 5,5
...........
...........
..3333333..
..3.....3..
..3.....3..
..3.....3..
..3.....3..
..3.....3..
..3333333..
...........
...........

(這可能會有更有效和/或更優雅的解決方案,具體取決於瓷磚的精確表示方式,但我認為該瓷磚易於理解且普遍適用,因為它僅提供一組坐標,而不能對基礎數據結構進行假設)。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM