最終確認日

オンラインゲームの仕組みの本ー第4章をGodotに置き換えながら読む

概要

チャットプログラムを作る

まずは読む

  • 片方がサーバー、片方がクライアントとなる
  • 3章で使った TranportTCP.csPacketQueue.cs が必要になる
  • チャット参加後は 毎フレーム呼ばれるUpdate 関数で、送信と受信の処理を退出するまで繰り返す
  • ChatState を用意しておくといい
  • ユーザーからのインプットがあったときに何かを実行するのではなく、Stateを変更して、毎フレームそれを監視してアクションを行う感じ
    • 退出ボタンを押す
      • この時は ChatState のみを変更する
    • 次のUpdate関数が呼ばれるときに実際に退出処理をしている
    • UIイベントで直接重い処理をせず、状態遷移だけを行うことで、ロジックの整合性を保ち、処理の分離を実現している。
    • GUI関数(ChattingGUI())では m_state の変更にとどめ、重い/危険な処理は Update() 側に委ねる設計。
    • Swiftだとユーザーからのイベント駆動で処理をすることが多いので、ボタン押下で直接処理を呼び出しちゃいそうだけど、頭を切り替えないとダメね。

置き換えてみる

画面

  • Robby.tscn 最初のタイトル画面
    • CreateRoomButton ホストを選択して部屋を作成する
    • JoinRoomButton クライアントとして部屋に入る
      • IPアドレスを入力する
      • エラーハンドリングをする
  • ChatRoom.tscn チャットルーム画面
    • LeaveButton 退出ボタン
    • SendMessageButton メッセージを送信ボタン
    • MessageField メッセージを表示するテキストフィールド

通信

  • TransportTCP.tscn 通信ライブラリ(3章で作った)

  • PacketQueue.gd 送受信するデータを保存するキュー(3章でつくった)

  • Chat.tscn チャットプログラム

    • ChatState を定義する
    • ChatRoom から送信/受信処理を呼び出す
  • これらは Autoload で設定する必要がありそう。

  • Godotでモバイル向けの環境設定をする

  • 画像を使ったボタンの配置方法を忘れた。

  • call_deferred("emit_signal", "data_received", data) のようにバックグラウンドスレッドからシグナルを呼んでメインスレッドに渡して実行する場合には call_deffered をしないとエラーになる。

このPoll関数がないとやっぱりうまくいかない。書く必要がある。

func _process(delta):
    if _socket == null or _socket.get_status() == StreamPeerTCP.STATUS_CONNECTED:
        return
    _socket.poll()  # ここが必要(クライアント側だけ)
    if _socket.get_status() == StreamPeerTCP.STATUS_CONNECTED:
        print("接続完了!")
サイトアイコン
公開日
更新日