You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java Roguelike游戏中如何检测3D数组内最高Z层级的对象?

Rogue类Java游戏Tile分层渲染实现

我正在开发一款类似1980年《Rogue》的Java小游戏,已经在draw()方法里实现了Tile渲染系统,现在正从Tile的2D数组过渡到3D数组——这样玩家走过的Tile能被保留下来。目前默认Tile(墙体、地面装饰、金币)被放在Z层级0,玩家Tile放在Z层级1,我的目标是每个网格位置只渲染最高Z层级的Tile。

以下是当前的draw方法代码:

public void draw(Graphics g) {
    Font font = new Font("TimesRoman", Font.BOLD, tileSize);
    g.setFont(font);

    // 绘制网格线
    g.setColor(Color.gray);
    for (int i = 0; i < boardWidth / tileSize; i++) {
        g.drawLine(i * tileSize, 0, i * tileSize, boardHeight);
        g.drawLine(0, i * tileSize, boardWidth, i * tileSize);
    }

    //Debug输出
    //System.out.println("Player coordinates: X=" + player.getX() + ", Y=" + player.getY());

    // 绘制实体Tile
    g.setColor(Color.white);
    for (int i = 0; i < boardWidth / tileSize; i++) {
        for (int j = 0; j < boardHeight / tileSize; j++) {
            for (int k = 0; k < 1; k++) {
                Tile t = tiles[i][j][k];
                if (t != null) {  //避免空指针异常
                    switch (t.getType()) {
                        case NULL:
                            break;
                        case DECO:
                            g.setColor(Color.CYAN);
                            break;
                        case ENTITY:
                            g.setColor(Color.blue);
                            break;
                        case PLAYER:
                            g.setColor(Color.green);
                            break;
                        case WALL:
                            g.setColor(Color.lightGray);
                            break;
                        case ENEMY:
                            g.setColor(Color.red);
                            break;
                        case LOOTABLE:
                            g.setColor(Color.yellow);
                            break;
                        default:
                            g.setColor(Color.white);
                            break;
                    }
                    g.drawString(String.valueOf(t.getChar()), t.getX() * tileSize, t.getY() * tileSize);
                }
            }
        }
    }
}

实现目标的修改方案

要实现“只渲染每个网格最高Z层级Tile”的需求,只需要调整Z层级的遍历顺序:从最高层级往下找,找到第一个非空的Tile就渲染它,然后跳过当前网格的其他层级。

修改后的draw方法代码:

public void draw(Graphics g) {
    Font font = new Font("TimesRoman", Font.BOLD, tileSize);
    g.setFont(font);

    // 绘制网格线
    g.setColor(Color.gray);
    for (int i = 0; i < boardWidth / tileSize; i++) {
        g.drawLine(i * tileSize, 0, i * tileSize, boardHeight);
        g.drawLine(0, i * tileSize, boardWidth, i * tileSize);
    }

    // 绘制实体Tile
    g.setColor(Color.white);
    // 动态获取Z层级的总深度
    int maxZLevel = tiles[0][0].length;
    for (int i = 0; i < boardWidth / tileSize; i++) {
        for (int j = 0; j < boardHeight / tileSize; j++) {
            // 从最高Z层级倒序遍历
            for (int k = maxZLevel - 1; k >= 0; k--) {
                Tile t = tiles[i][j][k];
                if (t != null) {
                    switch (t.getType()) {
                        case NULL:
                            continue;
                        case DECO:
                            g.setColor(Color.CYAN);
                            break;
                        case ENTITY:
                            g.setColor(Color.blue);
                            break;
                        case PLAYER:
                            g.setColor(Color.green);
                            break;
                        case WALL:
                            g.setColor(Color.lightGray);
                            break;
                        case ENEMY:
                            g.setColor(Color.red);
                            break;
                        case LOOTABLE:
                            g.setColor(Color.yellow);
                            break;
                        default:
                            g.setColor(Color.white);
                            break;
                    }
                    g.drawString(String.valueOf(t.getChar()), t.getX() * tileSize, t.getY() * tileSize);
                    // 找到最高层级Tile后,跳出当前网格的Z层级循环
                    break;
                }
            }
        }
    }
}

关键修改点说明

  • 倒序遍历Z层级:从maxZLevel - 1(最高层级)开始往下遍历,确保第一个找到的非空Tile就是当前网格最上层的可见Tile。
  • 找到后立即break:避免重复渲染下层被遮挡的Tile,提升渲染效率。
  • 动态获取maxZLevel:通过tiles[0][0].length获取Z层级总深度,不用硬编码数值,后续扩展更多层级时更灵活。

内容的提问来源于stack exchange,提问作者Lum1te

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.30 13:38:13