https://linen.dev logo
MHと警笛
# forum
f
MHと警笛それぞれをキーを割り当てて流すことってできますかね?
h
マイクラ側の基本機能(キー設定)から割当をする、という方法はわかりませんが、一般的?には描画スクリプトでキー入力を検知→dataMap送信→サーバースクリプトや音声スクリプトで処理を実装する、というやり方が主流かなと思います。 1.キー入力の検知とデータ送信(描画スクリプト) キー入力を検知する際は描画スクリプトで行うのですが、実装時に以下の点について注意する必要があります。 ・キー入力を検知するプレイヤーを限定する ・毎フレームパケット送信をしないような工夫をする 前者はマルチプレイで運転士以外のキーを検知しないようにするため、後者は負荷軽減のためです。
Copy code
js
    var isOldVer = Packages.jp.ngt.rtm.RTMCore.VERSION.indexOf("1.7.10") !== -1;//1.7.10かそれ以外(1.12か)を判別する

    var dataMap = entity.getResourceState().getDataMap();//dataMapを用いて値の持ち越しや他のスクリプトと同期します。
    var dataMapIsKeyDownHorn = dataMap.getBoolean("isKeyDownHorn");
    var dataMapIsKeyDownMH = dataMap.getBoolean("isKeyDownMH");
    var isKeyDownHorn = Keyboard.isKeyDown(Keyboard.KEY_P);// Keyboard.isKeyDown() は引数のキーが押されているかどうかをチェックします
    var isKeyDownMH = Keyboard.isKeyDown(Keyboard.KEY_O);

    //車両に乗っているプレイヤーを取得
    var driver = null;
    if (isOldVer) {
        driver = entity.field_70153_n;//車両の運転士を取得する処理(1.7.10)
    }
    else {
        driver = entity.func_184187_bx();//車両の運転士を取得する処理(1.12)
    }

    //スクリプトを実行しているプレイヤー(クライアント側)を取得
    var player = Packages.jp.ngt.ngtlib.util.NGTUtil.getClientPlayer();

    //プレイヤー === 運転士 と限定することで、マルチプレイで運転士以外のプレイヤーからのキー検知を無効化する
    if (player === driver) {
        //キー入力と保存されているデータに相違があるときだけ保存処理を実行する → 無駄にパケットを送信しないようにする
        if (isKeyDownHorn !== dataMapIsKeyDownHorn) {
            dataMap.setBoolean("isKeyDownHorn", isKeyDownHorn, 1); //"isKeyDownHorn"という名前にisKeyDownHornの変数の内容(Boolean型)を保存する 最後の1はサーバースクリプトや音声スクリプトで同期するために必要
        }

        if (isKeyDownMH !== dataMapIsKeyDownMH) {
            dataMap.setBoolean("isKeyDownMH", isKeyDownMH, 1);
        }
    }
2.音声を一度だけ実行する(音声スクリプト) キー入力の検知は押している間はずっとtrueのままであるため、警笛や放送などを1度だけ再生するにはOFF→ONの立ち上がりを検知しなければいけません。 そのために、直前のTickのときの入力値をdataMapで保存し、比較することで立ち上がりを検知します。
Copy code
js
    var entity = su.getEntity();
    var dataMap = entity.getResourceState().getDataMap();

    var isKeyDownHorn = dataMap.getBoolean("isKeyDownHorn");    //描画スクリプトからのキー入力
    var isKeyDownMH = dataMap.getBoolean("isKeyDownMH");        //描画スクリプトからのキー入力
    var prevIsKeyDownHorn = dataMap.getBoolean("prevIsKeyDownHorn");    //直前のTickのキー入力状態
    var prevIsKeyDownMH = dataMap.getBoolean("prevIsKeyDownMH");        //直前のTickのキー入力状態

    dataMap.setBoolean("prevIsKeyDownHorn", isKeyDownHorn, 0);    //次のTickへ検知状態を持ち越すため保存する。フラグの0は非同期でパケット送信を伴わないため、スクリプト内で完結する場合は0にする。
    dataMap.setBoolean("prevIsKeyDownMH", isKeyDownMH, 0);

    if (isKeyDownHorn === true && prevIsKeyDownHorn !== true) { //現在キー入力がされている AND 直前ではキー入力されていない という条件でOFF→ONの立ち上がりを検知する
        su.stopSound("sound_◯◯", "e259.horn"); //SEなど1度だけ再生する(非ループ音源)処理でも、次に再生するまでにstopをかけないと再生できなくなる
        su.playSound("sound_◯◯", "e259.horn", 1, 1, false); //引数は (ドメイン, 音声名(sounds.jsonで定義したもの), 音量, ピッチ, ループするかどうか)
    }

    if (isKeyDownMH && !prevIsKeyDownMH) { //省略形の条件分岐の書き方(条件は上と同じ)
        su.stopSound("sound_◯◯", "e259.mh");
        su.playSound("sound_◯◯", "e259.mh", 1, 1, false);
    }
※コードの動作性については検証していませんので、ミス等あればご容赦ください。