2 votes

Créer un champ hexagonal avec des tuiles plates avec JavaFX

Je veux créer un champ hexagonal avec des tuiles plates en JavaFX. La question suivante de stackoverflow permet de créer un champ avec des tuiles pointues : Créer un champ hexagonal avec JavaFX

Cet exemple de code fonctionne parfaitement avec les tuiles pointues :

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));
        }
    }
}

Je pense que je dois seulement modifier la partie ici :

     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
     );

mais j'ai du mal à obtenir une forme et une position correctes pour mes tuiles. Et si je le fais :

  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
  );

les tuiles ont une forme plate correcte mais ne sont pas positionnées correctement les unes par rapport aux autres. Je pense que cette fois, je dois modifier le code suivant :

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

Un exemple des tuiles pointues obtenues avec ce code :

enter image description here

1voto

Hervé Girod Points 121

J'ai trouvé une solution pour les tuiles plates. La voici :

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));
      }
   }
}

Le résultat est :

enter image description here

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X