py-mcwsでプレイヤーの前に任意のブロックを置いてみる

マインクラフトでプレイヤーの前に任意のブロックを置いてみます。

今回は例として砂(ブロックID:sand)を置いてみます。


Pythonで任意のブロックを設置するコードを作成する前に、マインクラフトのコマンドで動作を確認してみます。

マインクラフトでは任意のブロックを設置する為に

/setblock x y z ブロックID ブロック状態 オプション

※ブロック状態以後のパラメータは省略可

のコマンドが用意されていますので、先にsetblockの挙動を調べておきます。


setblockの次に指定するx座標、y座標、z座標はpy-mcwsでプレイヤーの頭上でニワトリを召喚してみるで触れました~(チルダ)を利用すればプレイヤーの近くを簡単に指定することができますが、~(チルダ)ではプレイヤーがどの方向を向いているか?を把握する術がありません。


マインクラフトの座標の指定では~(チルダ)の他に^(キャレット)による指定の方法があります。

^(キャレット)は~(チルダ)同様、^ ^ ^1のようにプレイヤーからどれ程離れた場所を指定する方法になりまして、

/setblock ^ ^ ^ sand

のキャレットの左から、左右、上下、前後の指定をすることができます。


例えば、プレイヤーの前にブロックを置きたいということであれば、三番目のキャレットの値に1を足し、

/setblock ^ ^ ^1 sand

のように指定すれば良いです。


余談ですが、~(チルダ)で指定する座標は相対座標と呼び、^(キャレット)で指定する座標はローカル座標と呼びます。

座標 - Minecraft Wiki


ただ、この指定方法には少々問題がありまして、その問題を動画を見ながら確認していきます。




2つの動画はどちらもプレイヤーが同じ座標で同じコマンド(下記のコマンド)だけれども、プレイヤーの視点が異なっている時の動作になります。

/setblock ^ ^ ^1 sand

1つ目の動画はプレイヤーがどちらかというと下を向いている時、砂ブロックが設置される場所はy座標が一つ下(~-1に相当)になりました。


2つ目の動画はプレイヤーが正面を向いている時、砂ブロックはy座標は同じでプレイヤーの前に置かれました。


py-mcwsでプレイヤーの前に任意のブロックを設置したい場合はプレイヤーの視点等を意識する必要があることがわかりました。

他に検証動画はありませんが、下記の二点も意識する必要があります。

・ブロックを置くときの各座標は整数を指定するが、プレイヤーが移動できる座標は小数点第2位までの実数を用いている

・プレイヤーは北西や南東等の四方向以上の方向を向くことができる。




今までの流れを踏まえまして、py-mcwsでプレイヤーの前にブロックを置くコードを作成してみます。

今回はチャットとコマンドの画面で$bというメッセージを送信した時に砂(sand)を置いてみます。


/home/******(ユーザ名が入る)/workspace/ws-server/main.pyのファイルを下記のように書き換えてみます。

import py_mcws

server = py_mcws.WebsocketServer()

@server.event
async def on_ready(host, port):
    print(f"サーバーを起動しました。\n'/connect {host}:{port}'で接続できます")

@server.event
async def on_connect():
    print("接続しました")

@server.event
async def on_PlayerMessage(event):
    if event["body"]["message"] == "$b":
        await server.command("tp ~ ~ ~ ~ 0")
        await server.command("setblock ^ ^ ^1 sand")

server.start(host="0.0.0.0", port=19132)

今回のコードで注目すべき点はsetblockのコマンドの前にtpコマンドで現在位置にテレポートする処理を追加していることです。

tpコマンドは

/tp x y z 方位 目線 テレポート先に任意のブロックがあるか?

※方位以降のパラメータは省略可

※tpコマンドに関しては今回のコマンドは一例で、他にもパラメータの指定方法があります。


await server.command("tp ~ ~ ~ ~ 0")

にすることで、x座標、y座標、z座標は同じ場所で、向いている方位も同じですが、目線は真正面を向いた状態でテレポートという命令になります。

※目線は-90が真上、0が正面で90が真下になります。


本当は各座標を取得して、実数値から整数値に整形して直接指定したかったのですが、PlayerMessageイベントではプレイヤーの位置情報を得る手段がありませんでしたので、不格好な形にはなりますが、tpコマンドで目線の調整のみ行います。


それでは早速サーバを立ち上げ、マインクラフトと接続してコードを試してみます。



$bのメッセージを送信後に目線のみが調整され、プレイヤーの前に砂ブロックが置かれました。

マインクラフト用ビジュアルエディタを開発しています。
詳しくはinunosinsi/mcws_blockly - githubをご覧ください。