显示等距图块时的 Z 顺序问题

问题描述 投票:0回答:1

我在学校游戏中显示等距图块时遇到了一些问题。 事实是,我认为我的代码一切正常......

它的组织方式如下:

  • 架构:MVC + ECS
  • 一切都显示在我的 GameView 类的渲染方法中
  • 我使用基数和矢量在两个基数(正交基数和等距基数)之间进行转换

这是代码:

public void render() {
    try {
        final Entity[] entities = this.controller.getEntities();

        // Sort entities by isometric depth
        Arrays.sort(entities, (e1, e2) -> {
            PositionComponent p1 = e1.getComponent(PositionComponent.class);
            PositionComponent p2 = e2.getComponent(PositionComponent.class);

            // Calculate depth as the sum of cartesian x + y
            double depth1 = p1.getX() + p1.getY();
            double depth2 = p2.getX() + p2.getY();

            // Primary sorting criterion: depth
            int result = Double.compare(depth1, depth2);

            // Secondary sorting: cartesian Y coordinate
            if (result == 0) {
                result = Double.compare(p1.getY(), p2.getY());
            }

            // Tertiary sorting: cartesian X coordinate
            if (result == 0) {
                result = Double.compare(p1.getX(), p2.getX());
            }

            // Fallback sorting: hashCode
            if (result == 0) {
                result = Integer.compare(e1.hashCode(), e2.hashCode());
            }

            return result;
        });

        for (Entity entity : entities) {
            // Get position component
            PositionComponent position = entity.getComponent(PositionComponent.class);

            // Convert to isometric coordinates
            Vector isoPos = this.gameBase.mulByVect(
                new Vector2D(position.getX(), position.getY())
            );

            // Debug: print isometric position
            // System.out.println("Isometric Position: " + isoPos);

            // Get texture component
            ImageIcon image = entity.getComponent(TextureComponent.class).getTexture();

            // Create label for the entity
            JLabel label = new JLabel(image);

            // Set bounds based on isometric position
            label.setBounds(
                (int) isoPos.getEntry(0),
                (int) isoPos.getEntry(1),
                image.getIconWidth(),
                image.getIconHeight()
            );

            this.panel.add(label);
        }

        // Revalidate and repaint after adding all entities
        this.panel.revalidate();
        this.panel.repaint();

    } catch (Exception e) {
        e.printStackTrace();
    }
}

但是,图块显示效果不佳。事实上,最远的显示在最近的显示之后,所以看起来像是翻转了......

你有什么想法吗?

当然,如果需要的话,请随意提问!

非常感谢!

java algorithm isometric
1个回答
0
投票

您面临的问题可能是由您计算和比较实体深度进行排序的方式引起的。由于您使用的是等距图块,因此渲染顺序应确保靠近屏幕(或右下角)的图块在较远(或左上)的图块之后绘制。

在当前代码中,您将深度计算为笛卡尔 x+yx+y 的总和,但这可能无法正确捕获用于渲染目的的等距深度排序。 该深度可以计算为 深度=p1.getY()−p1.getX() 深度 =p1.getY()−p1.getX(),假设您的等距变换符合此逻辑。

// Sort entities by isometric depth
Arrays.sort(entities, (e1, e2) -> {
    PositionComponent p1 = e1.getComponent(PositionComponent.class);
    PositionComponent p2 = e2.getComponent(PositionComponent.class);

    // Calculate depth based on isometric Y-X
    double depth1 = p1.getY() - p1.getX();
    double depth2 = p2.getY() - p2.getX();

    // Primary sorting criterion: depth
    int result = Double.compare(depth1, depth2);

    // Secondary sorting: cartesian Y coordinate
    if (result == 0) {
        result = Double.compare(p1.getY(), p2.getY());
    }

    // Tertiary sorting: cartesian X coordinate
    if (result == 0) {
        result = Double.compare(p1.getX(), p2.getX());
    }

    // Fallback sorting: hashCode
    if (result == 0) {
        result = Integer.compare(e1.hashCode(), e2.hashCode());
    }

    return result;
});

© www.soinside.com 2019 - 2024. All rights reserved.