【问题标题】:JAVA Visual RepresentationJAVA 视觉表示
【发布时间】:2018-02-09 22:58:56
【问题描述】:

我一直在寻找一种方法来制作 Java 的静态视觉表示,但我不确定我发现什么是完成我正在寻找的最正确的方法。

我正在寻找一种方法来简单地生成一个图像来表示 Java 中的板的状态。例如,假设我有一个 Java 中的 Checkers 实现,我正在寻找一种在每个单独的移动之后代表游戏板的方法。

我研究过 JavaFX 和 Swing,但从我发现它们更适合实际动态 GUI 的情况来看,而不是图像处理(我可能是错的)。

真的有哪些选择?或者我应该为此使用任何外部应用程序/软件吗?

【问题讨论】:

  • what im looking for is a way to, after each individual move, represent the game board. - 如果你的意思是你只想创建一个图像,那么你可以使用Screen Image 类。它允许您创建任何 Swing 组件的图像。
  • “我正在寻找的是一种在每次移动后代表游戏板的方法”->这不是“实际的动态 GUI”吗?你能更好地解释你想要做什么吗?什么是“Java 的静态视觉表示”?
  • Camickr,如果可以选择不使用 swing 我更喜欢,因为每次执行操作时不断创建窗格会很痛苦
  • Jewelsea,因为它根本不是 gui,也不是动态的,它不会改变也不会接受任何输入,k 我正在寻找的只是在每次操作后生成图像,而不是查看对于某种“可更新”的 gui

标签: java swing image-processing javafx


【解决方案1】:

您可以尝试这样的方法(JavaFX 解决方案),它将棋盘的图像呈现为 png 文件。不确定这是否是您正在寻找的,因为您的问题对我来说有点不清楚,但也许它对您有帮助。



import javafx.application.*;
import javafx.embed.swing.SwingFXUtils;
import javafx.scene.*;
import javafx.scene.image.WritableImage;
import javafx.scene.paint.Color;
import javafx.scene.shape.Circle;
import javafx.scene.shape.Rectangle;
import javafx.stage.Stage;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.nio.file.*;
import java.util.ArrayList;
import java.util.List;

public class Checkout extends Application {

    private static final double SQUARE_SIZE = 20;
    private static final double PIECE_RADIUS = SQUARE_SIZE / 2.5;

    private static final Color WHITE = Color.BEIGE;
    private static final Color BLACK = Color.ROSYBROWN;

    // setupindex, player, position (1-32 index into top to bottom black squares on the board).
    private static final int[][][] setups =
            {
                    {
                            {31, 27, 19},
                            {17, 12, 5}
                    },
                    {
                            {30, 26, 18},
                            {19, 11, 10},
                    },
                    {
                            {31, 24, 19},
                            {18, 11, 10}
                    }
            };
    private static final String SNAPSHOT_FILE_PREFIX = "snapshot-";
    private static final String SNAPSHOT_FILE_SUFFIX = ".png";

    private WritableImage snapshotFxImage =
            new WritableImage((int) (SQUARE_SIZE * 8), (int) (SQUARE_SIZE * 8));
    private BufferedImage snapshotBufferedImage =
            new BufferedImage((int) (SQUARE_SIZE * 8), (int) (SQUARE_SIZE * 8), BufferedImage.TYPE_INT_ARGB);

    private static final String USER_HOME =
            System.getProperties().getProperty("user.home");


    @Override
    public void start(Stage stage) throws IOException {
        Group layout = new Group();
        renderBoard(layout);
        Scene scene = new Scene(layout);

        int i = 0;
        for (int[][] setup : setups) {
            List<Node> pieces = renderSetup(setup);
            layout.getChildren().addAll(pieces);
            snapshot(scene, i);
            layout.getChildren().removeAll(pieces);

            i++;
        }

        Platform.setImplicitExit(false);
        Platform.exit();
    }

    private void renderBoard(Group layout) {
        for (int r = 0; r < 8; r++) {
            for (int c = 0; c < 8; c++) {
                Rectangle square = new Rectangle(
                        c * SQUARE_SIZE,
                        r * SQUARE_SIZE,
                        SQUARE_SIZE,
                        SQUARE_SIZE
                );

                Color fill =
                        (((c + r) % 2) == 0)
                                ? Color.WHITE
                                : Color.BLACK;
                square.setFill(fill);

                layout.getChildren().add(square);
            }
        }
    }

    private List<Node> renderSetup(int[][] setup) {
        List<Node> pieces = new ArrayList<>();
        for (int player = 0; player < 2; player++) {
            for (int pieceIndex = 0; pieceIndex < setup[player].length; pieceIndex++) {
                Color fill =
                        player == 0
                                ? WHITE
                                : BLACK;
                Circle piece = new Circle(PIECE_RADIUS, fill);

                pieces.add(piece);
                movePieceTo(piece, setup[player][pieceIndex]);
            }
        }

        return pieces;
    }

    private void movePieceTo(Circle circle, int p) {
        int r = (p - 1) / 4;
        int c = ((p - 1) % 4) * 2 + (((r % 2) == 0) ? 1 : 0);

        circle.setCenterX(c * SQUARE_SIZE + SQUARE_SIZE / 2);
        circle.setCenterY(r * SQUARE_SIZE + SQUARE_SIZE / 2);
    }

    private void snapshot(Scene scene, int snapshotIdx) throws IOException {
        Path path = Paths.get(
                USER_HOME,
                SNAPSHOT_FILE_PREFIX + snapshotIdx + SNAPSHOT_FILE_SUFFIX
        );
        scene.snapshot(snapshotFxImage);
        SwingFXUtils.fromFXImage(snapshotFxImage, snapshotBufferedImage);
        ImageIO.write(snapshotBufferedImage, "png", path.toFile());

        System.out.println("Saved: " + path.toString());
    }

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

【讨论】:

    【解决方案2】:

    您可以使用Graphics 类来绘制内存中的图像。然后您可以将其保存到文件或以某种方式显示。以下是您如何开始这样做的示例:

    import javax.imageio.ImageIO;
    import java.awt.*;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    
    public class SO45990731 {
    
        public static void main(String [] args) throws IOException {
            BufferedImage image = new BufferedImage(500, 500, BufferedImage.TYPE_INT_ARGB);
    
            Graphics g = image.getGraphics();
    
            // TODO draw your checker board
            g.drawOval(100, 100, 300, 300);
    
            // cleanup and write
            g.dispose();
            ImageIO.write(image, "png", new File("board.png"));
        }
    }
    

    【讨论】:

    • 不是最漂亮的解决方案,但以简单的方式解决了问题,非常感谢
    • @eXistanCe 这种方式是在 Java 中绘制图像的一种非常标准的方式。您还可以考虑读取您的棋盘图像,然后将这些棋子(或使用g.drawImage() 从其他图像中放置它们)绘制到结果上。这将使创建漂亮的输出变得更容易,而无需在 java 中完成所有操作。
    • @eXistanCe 差点忘了,Graphics 对象可以转换为 Graphics2D 类,为您提供更多绘图功能。
    • 您的意思是加载棋盘的自定义图像,然后使用该类来绘制棋子?
    • @eXistanCe 您可以在项目中保留棋盘、红色棋子、黑色棋子和国王版本的图像。只需加载这些图像并将它们绘制到您的新图像上,这样您就可以使它们看起来很漂亮。这也很容易。
    猜你喜欢
    • 2011-05-29
    • 1970-01-01
    • 1970-01-01
    • 2014-10-17
    • 2012-02-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多