Minecraft で Java (2) ソースコード編集

前回エントリ「Minecraft で Java (1) 環境構築編」の続きです。
前回の内容でエラーが発生せず、成功したことを前提とします。

1. ソースコードを開く

Minecraft Forge をインストールしたディレクトリにある \src\main\java\com\example\examplemod ディレクトリを開きます。

そこにある、 ExampleMod.java を好きなエディタで開きます。
Windows 標準のメモ帳でも編集は可能ですが、行番号の表示や字下げ補助のあるエディタのほうが楽です。
人によって使用するエディタは十人十色ですが、参考までに自分はサクラエディタ、秀丸、Notepad++ などいろいろ使ってみたところ、最終的に Sublime Text に落ち着きました。

2. ソースコードを編集

ここからが本番です。
文章だけでは説明に限界がありますので、大まかな雰囲気と思っていただければと思います。
今回は、予め用意された画像データに基づき、マウスを左クリックしたら壁画を、右クリックしたら地上絵を像を描画するというコードを記載します。

@Mod(ExampleMod.MODID)
public class ExampleMod {
    //(略)
    // 画像イメージのテキストファイル名から文字列型配列を返す
    public List<String> getGazouFromText(String gazou_file) {
        List<String> lines = new ArrayList<>();
        try {
            // run ディレクトリを起点
            InputStream input = new FileInputStream(gazou_file);
            BufferedReader reader = new BufferedReader(new InputStreamReader(input, StandardCharsets.UTF_8));
            String line;
            while ((line = reader.readLine()) != null) {
                lines.add(line.trim());
            }
        }
        catch (FileNotFoundException e) {
            System.out.println("file not found: " + gazou_file);
        }
        catch (Exception e) {
            e.printStackTrace();
        }
        return lines;
    }

    // XY平面に描画
    public void drawPictureXY(ServerLevel level, ServerPlayer player) {
        List<String> lines = getGazouFromText("gazouXY.txt");
        // プレイヤーの現在地を基準に
        int originX = player.getBlockX() - lines.get(0).length() / 2;
        int originY = player.getBlockY() + lines.size();
        int originZ = player.getBlockZ() - lines.size() / 2;

        for (int y = 0; y < lines.size(); y++) {
            String row = lines.get(y);
            for (int x = 0; x < row.length(); x++) {
                char c = row.charAt(x);
                int colorIndex = SYMBOLS_FROM_TEXT.indexOf(c);
                if (colorIndex >= 0 && colorIndex < COLOR_BLOCKS.length) {
                    Block block = COLOR_BLOCKS[colorIndex];
                    BlockPos pos = new BlockPos(originX + x, originY - y, originZ);
                    level.setBlock(pos, block.defaultBlockState(), 3);
                }
            }
        }
    }

    // XZ平面に描画
    public void drawPictureXZ(ServerLevel level, ServerPlayer player) {
        List<String> lines = getGazouFromText("gazouXZ.txt");
        // プレイヤーの現在地を基準に
        int originX = player.getBlockX() - lines.get(0).length() / 2;
        int originY = player.getBlockY() ;
        int originZ = player.getBlockZ() - lines.size() / 2;

        for (int z = 0; z < lines.size(); z++) {
            String row = lines.get(z);
            for (int x = 0; x < row.length(); x++) {
                char c = row.charAt(x);
                int colorIndex = SYMBOLS_FROM_TEXT.indexOf(c);
                if (colorIndex >= 0 && colorIndex < COLOR_BLOCKS.length) {
                    Block block = COLOR_BLOCKS[colorIndex];
                    BlockPos pos = new BlockPos(originX + x, originY, originZ + z);
                    level.setBlock(pos, block.defaultBlockState(), 3);
                }
            }
        }
    }

    //(略)
    // 左クリック時に実行
    @SubscribeEvent
    public void kansuu21(PlayerInteractEvent.LeftClickBlock event) {
        if (!(event.getEntity() instanceof ServerPlayer player)){
            return;
        }
        ServerLevel level = (ServerLevel) player.level();
        drawPictureXY(level, player);
    }

    // 右クリック時に実行
    @SubscribeEvent
    public void kansuu22(PlayerInteractEvent.RightClickBlock event) {
        if (!(event.getEntity() instanceof ServerPlayer player)){
            return;
        }
        ServerLevel level = (ServerLevel) player.level();
        drawPictureXZ(level, player);
    }
    //(略)
}

3. 実行

前回同様、Minecraft Forge をインストールしたディレクトリで以下を実行します。

gradlew runClient

実行するとこのような画面が出ます。

マシンスペックにもよりますが数十秒で Minecraft が起動します。
前回作ったワールドあるいは新規ワールドで開始します。

左クリックします。

マシンスペックにもよりますが数秒後に壁画が生成されます。

空中に浮かぶと全体像が見えます。

右クリックでは地上絵を描画できます。

上空から見たところです。

斜めから見下ろして、2枚の写真を見比べられます。

4. 応用例

今回は風景写真でしたが、家族写真でも同じことが可能です。
数年前の写真を壁画に、全く同じポーズで今年撮った写真を地上絵にするのも面白いかと思います。


分類:

記載日

投稿者: