【问题标题】:Create hexagonal field with flat tiles with JavaFX使用 JavaFX 创建带有平面图块的六边形字段
【发布时间】:2021-09-08 17:43:11
【问题描述】:

我想在 JavaFX 中创建一个带有平面图块的六边形字段。下面的 stackoverflow 问题允许创建一个带有尖头图块的字段:Create hexagonal field with JavaFX

此代码示例与尖头瓷砖完美搭配:

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;
import javafx.stage.Stage;

public class UISolution extends Application {

    private final static int WINDOW_WIDTH = 800;
    private final static int WINDOW_HEIGHT = 600;

    private final static double r= 20; // the inner radius from hexagon center to outer corner
    private final static double n= Math.sqrt(r * r * 0.75); // the inner radius from hexagon center to middle of the axis
    private final static double TILE_HEIGHT = 2 * r;
    private final static double TILE_WIDTH = 2 * n;

    public static void main(String[] args) {
        launch(args);
    }

    public void start(Stage primaryStage) {
        AnchorPane tileMap = new AnchorPane();
        Scene content = new Scene(tileMap, WINDOW_WIDTH, WINDOW_HEIGHT);
        primaryStage.setScene(content);

        int rowCount = 4; // how many rows of tiles should be created
        int tilesPerRow = 6; // the amount of tiles that are contained in each row
        int xStartOffset = 40; // offsets the entire field to the right
        int yStartOffset = 40; // offsets the entire fiels downwards

        for (int x = 0; x < tilesPerRow; x++) {
            for (int y = 0; y < rowCount; y++) {
                double xCoord = x * TILE_WIDTH + (y % 2) * n + xStartOffset;
                double yCoord = y * TILE_HEIGHT * 0.75 + yStartOffset;
                
                Polygon tile = new Tile(xCoord, yCoord);
                tileMap.getChildren().add(tile);
            }
        }
        primaryStage.show();
    }

    private class Tile extends Polygon {
        Tile(double x, double y) {
            // creates the polygon using the corner coordinates
            getPoints().addAll(
                    x, y,
                    x, y + r,
                    x + n, y + r * 1.5,
                    x + TILE_WIDTH, y + r,
                    x + TILE_WIDTH, y,
                    x + n, y - r * 0.5
            );

            // set up the visuals and a click listener for the tile
            setFill(Color.ANTIQUEWHITE);
            setStrokeWidth(1);
            setStroke(Color.BLACK);
            setOnMouseClicked(e -> System.out.println("Clicked: " + this));
        }
    }
}

我想我只需要修改这里的部分:

     getPoints().addAll(
         x, y,
         x, y + r,
         x + n, y + r * 1.5,
         x + TILE_WIDTH, y + r,
         x + TILE_WIDTH, y,
         x + n, y - r * 0.5
     );

但我正在努力为我的瓷砖设置正确的形状和位置。如果我这样做:

  getPoints().addAll(x, y,
     x + n * 0.5, y + r,
     x + n * 1.5, y + r,
     x + TILE_WIDTH, y,
     x + n * 1.5, y - r,
     x + n * 0.5, y - r
  );

瓷砖具有正确的平面形状,但相对于彼此的位置不正确。我觉得这次应该修改如下代码:

     double xCoord = x * TILE_WIDTH + (y % 2) * n + xStartOffset;
     double yCoord = y * TILE_HEIGHT * 0.75 + yStartOffset;

使用此代码生成尖头图块的示例:

【问题讨论】:

  • 我修复了示例 RADIUS_N 为 n 并且 RADIUS_N 为 r
  • 感谢编辑:)
  • “平瓦”和“尖瓦”有什么区别?您能否提供您尝试创建的图块和字段的图像?您实际上是在尝试创建 regular octagon 而不是六边形吗?请注意,您不能创建仅由常规八边形组成的平铺字段。
  • 这个网站解释了很多关于扁平或尖头六边形网格的事情:redblobgames.com/grids/hexagons/ 遗憾的是,我仍然无法使用它来将最初的“尖头”JavaFX 实现更改为“扁平”的.

标签: java javafx hexagonal-tiles


【解决方案1】:

我找到了一个平地砖的解决方案。这里是:

package org.hexagon.check;

import javafx.application.Application;
import javafx.scene.Scene;
import javafx.stage.Stage;
import javafx.scene.layout.AnchorPane;
import javafx.scene.paint.Color;
import javafx.scene.shape.Polygon;

public class HexagonFlat extends Application {
   private final static double TILE_WIDTH = 20;
   private final static double TILE_HEIGHT = TILE_WIDTH;
   private final static int WINDOW_WIDTH = 800;
   private final static int WINDOW_HEIGHT = 600;
   double v = Math.sqrt(3) / 2.0;
   double v2 = Math.sqrt(3);

   public static void main(String[] args) {
      launch(args);
   }

   public void start(Stage primaryStage) {
      AnchorPane tileMap = new AnchorPane();
      Scene content = new Scene(tileMap, WINDOW_WIDTH, WINDOW_HEIGHT);
      primaryStage.setScene(content);

      int rowCount = 4; // how many rows of tiles should be created
      int tilesPerRow = 6; // the amount of tiles that are contained in each row
      int xStartOffset = 40; // offsets the entire field to the right
      int yStartOffset = 40; // offsets the entire fiels downwards
      for (int y = 0; y < rowCount; y++) {
         double yCoordInit = yStartOffset + y * TILE_WIDTH * v2;
         double yCoord = yCoordInit;
         for (int x = 0; x < tilesPerRow; x++) {
            double xCoord = 1.5 * x * TILE_WIDTH + xStartOffset;
            Polygon tile = new Tile(xCoord, yCoord);
            tileMap.getChildren().add(tile);
            yCoord = yCoord == yCoordInit ? yCoord + TILE_HEIGHT * v : yCoordInit;
         }
      }
      primaryStage.show();
   }

   private class Tile extends Polygon {
      Tile(double x, double y) {
         // creates the polygon using the corner coordinates
         getPoints().addAll(
            x, y,
            x + TILE_WIDTH, y,
            x + TILE_WIDTH * 1.5, y + TILE_HEIGHT * v,
            x + TILE_WIDTH, y + TILE_HEIGHT * v2,
            x, y + TILE_WIDTH * v2,
            x - (TILE_WIDTH / 2.0), y + TILE_HEIGHT * v
         );
         // set up the visuals and a click listener for the tile
         setFill(Color.ANTIQUEWHITE);
         setStrokeWidth(1);
         setStroke(Color.BLACK);
         setOnMouseClicked(e -> System.out.println("Clicked: " + this));
      }
   }
}

结果是:

【讨论】:

    猜你喜欢
    • 2019-06-07
    • 1970-01-01
    • 2015-01-12
    • 2023-04-08
    • 1970-01-01
    • 2023-03-20
    • 1970-01-01
    • 1970-01-01
    • 2019-06-15
    相关资源
    最近更新 更多