広告 Java Minecraft Spigot プログラミング

Spigotプラグイン開発(二段ジャンプ)②+タブ補完の実現

2021年6月6日

前回の記事では二段ジャンプのコマンド部分のみ実装しましたね。
今回の記事では中身の二段ジャンプそのものを実装していこうと思います。
少し難易度は上がりますが、この記事通りに開発を進めれば実装できると思います。
それでは行ってみよう!

前回の記事はこちら

[st-card-ex url="https://www.dice-programming-etc.com/spigot_plugin_double_jump1/" target="_blank" rel="nofollow" label="" name="" bgcolor="" color="" readmore=""]

今回のテーマ

プレイヤーの動作を検知してダブルジャンプを実行させることが今回のテーマになります。
重要なのは「プレイヤーの動作を検知」です。
動作を検知し、前回の記事で説明したメタデータと照らし合わせて二段ジャンプがONになっているかを判断してから二段ジャンプを実行する必要があります。
また、そのジャンプが一回目のジャンプか否かも判別する必要がありますね。
かなり複雑になりつつありますが、順番に実装していきましょう。

二段ジャンプ処理の実装

今回は二段ジャンプ処理用に「EventClass」を実装しましょう。

import org.bukkit.event.Listener;

public class EventClass implements Listener {
    
}

まずはメタデータ関係なく、二段ジャンプを実装してしまいましょう。
意外と難しくはありません。

public class EventClass implements Listener {

    @EventHandler
    public void onPlayerJoin(PlayerJoinEvent e){
        e.getPlayer().setAllowFlight(true);
    }

    @EventHandler
    public void onPlayerDoubleJump(PlayerToggleFlightEvent e) {
        Player p = e.getPlayer();
        if (p.getGameMode() == GameMode.SURVIVAL) {
            e.setCancelled(true);
            Block b = p.getWorld().getBlockAt(p.getLocation().subtract(0, 2, 0));
            if (!b.getType().equals(Material.AIR)) {
                Vector v = p.getLocation().getDirection().multiply(0.5).setY(0.5);
                p.setVelocity(v);
            }
        }
    }
}

これを丸写ししてしまいましょう。

まず5行目ですが、サーバーにログインした段階で飛行を許可してしまいます。
「え?飛行させるの?」と思うかもしれませんが、二段ジャンプは短時間の飛行みたいなものなのでこの許可が必要です。
許可しないと実装は難しくなってしまいます。
今回は簡単なプラグインなのでこれで十分です。

続いて、9行目~の飛行イベントになります。
11行目でサバイバルか否かを確認しています。
そして12行目で飛行イベントをキャンセルしています。
13行目で2ブロック下のブロックのデータを取得しています。
14行目で取得したブロックが空気か否かを判別しています。
空気ではなかった場合15,16行目でゴニョゴニョやっています。ベクトルのお話なので「何かやってるんだなぁ」くらいの認識で大丈夫です。

これで二段ジャンプの処理が実装できました。
こんな感じです。

オン・オフの切り替え

6行目と7行目の処理を追加します。

@EventHandler
public void onPlayerDoubleJump(PlayerToggleFlightEvent e) {
    Player p = e.getPlayer();
    if (p.getGameMode() == GameMode.SURVIVAL) {
        e.setCancelled(true);
        List<MetadataValue> list = p.getMetadata(WJ_KEY);
        if(list.get(0).value().toString().equalsIgnoreCase("on")){
            Block b = p.getWorld().getBlockAt(p.getLocation().subtract(0, 2, 0));
            if (!b.getType().equals(Material.AIR)) {
                Vector v = p.getLocation().getDirection().multiply(0.5).setY(0.5);
                p.setVelocity(v);
            }
        }
    }
}

6行目の処理ですが、メタデータを取得するだけなのになぜかList型……。
よくわからん。
まぁそれは置いておいて、前回の記事で用意したKeyを指定してメタデータをListに入れていきましょう。
その時、WJ_KEYはそのままでは使用できないのでimportしておきましょう。

import static com.dice_programming_etc.DoubleJump.CommandClass.WJ_KEY;

で、7行目のif文です。
この中でやっているのはメタデータが入っているListの0番目の値が「on」なのかを見る処理です。
onであれば二段ジャンプの実行。offであれば二段ジャンプは実行しないという感じです。

はい、これだけです。
ここまでできたらプラグインをコンパイルしてサーバーに突っ込みましょう。
サーバーにプラグインを入れたらそこにログインして

/wjump on

と打ってみてください。

二段ジャンプをONにしました。

とでればコマンドは実行できています。
メッセージが出たらジャンプボタンを二度押ししてみてください。
二段ジャンプができるようになっていると思います。
そして次は引数を「off」にしてコマンドを実行。次は

二段ジャンプをOFFにしました。

と出ると思います。
そうしたら同じようにジャンプボタンを二度押ししてみてください。
若干滞空時間が長くなる気もしますが、二段ジャンプはできなくなっていると思います。

以上で、コマンドの実装及び二段ジャンプの実装が完了しました。

【番外編】Tab補完

さて、続いて番外編です。
「Tab補完」と言っても「何それ?」と思う人の方が多そうですね。
まぁ、これです。

あまりこれについて言及している記事が無いと思ったので、コマンドを実装したついでとして番外編にしてみました。

Tab補完を実装するのはCommandClass.javaにします。
別のクラスに書いても良いですが、今回はCommandClassで十分です。
まず、以下の部分を修正します。

public class CommandClass  implements CommandExecutor {
public class CommandClass  implements CommandExecutor, TabCompleter {

implementsの部分に「,」で区切って「TabCompleter」を実装します。
そうしたらメソッドを定義しましょう。
「onCommand」メソッドがあると思います。その下にこれを書いてください。

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
    return null;
}

中の処理はこんな感じ。(あまり入れ子にはしたくないですが……)

@Override
public List<String> onTabComplete(CommandSender sender, Command command, String alias, String[] args) {
    if(command.getName().equalsIgnoreCase("wjump")){
        if (args.length == 1) {
            if (args[0].length() == 0) { // /wjumpまで
                return Arrays.asList("on","off");
            } else {
                if ("on".startsWith(args[0]) && "off".startsWith(args[0])) {
                    return Arrays.asList("on","off");
                }
                else if("on".startsWith(args[0])){
                    return Collections.singletonList("on");
                }
                else if("off".startsWith(args[0])){
                    return Collections.singletonList("off");
                }
            }
        }
    }
    return null;
}

これを実装するとこうなります。

以上!Tab補完の実装でした!

まとめ

どうでしたか?
「意外と簡単じゃね?」と思った人も「思ってたより難しかった」と思った人もいるでしょう。
感じ方は人それぞれです。
ただ、この記事がプラグイン開発のきっかけにでもなってくれればうれしいです。
今後もマイペースに記事を更新していくのでお楽しみに。

完成したソースコード

[st-card-ex url="https://github.com/DICE-10/DoubleJump" target="_blank" rel="nofollow" label="" name="" bgcolor="" color="" readmore=""]

-Java, Minecraft, Spigot, プログラミング
-, , ,