ローレベルな通信コマンドからの脱却(2)
伺かはSSTP通信を使ってメッセージを表示することができます。
特にローカルPC内でのメッセージ送信で使うのですが、文法的には次のようになります。
msg = "\\0\\f[height,14]\\s[0]明日の予測ですが・・・\\1\\f[height,14]\\s[10]えーと、明日も特に波乱はなさそうです。\\n"
send_one_msg(msg)
めんどくせーー、というのが前回の話でした。
簡単に使えるよう、まずは定義ファイルを作ろう
キャラクターID,表情名,サーフェスID
0,びっくり,964
0,びっくり,965
0,びっくり1,966
0,びっくり2,967
1,びっくり,1965
1,びっくり1,1966
0,怒り,7,コメント
1,落ち込み,304
1,落ち込み1,306
0,落ち込み,4
0,落ち込み1,202
1,驚き,11
1,驚き1,307
1,驚き2,310
1,驚き3,313
現在のサーフェスの実装状況を元に定義ファイルを作りましたが、次の問題があることがわかります。
キャラクター0の「びっくり」が2つ定義されている
キャラクター0に「びっくり2」があるが、キャラクター1には無い。
この定義ファイルを使うためには次のような要件になります。
複数定義されている表情名が指定されたら、その中からランダムにサーフェスIDを戻す。
キャラクターに存在しない末尾数値の表情名が指定されたら、末尾数値を無視してサーフェスIDを戻す。
見当違いな表情名がしていされたら、標準サーフェスIDを戻す。
Pythonで実装しよう
Pythonの辞書型は重複定義ができないので、拡張したクラスにします。
############################################################################################################
# 重複を許した特定のキーで辞書を追加する関数
############################################################################################################
def add_value_to_key(self, dictionary, key, value):
if key in dictionary:
dictionary[key].append(value) # キーが存在する場合、値をリストに追加
else:
dictionary[key] = [value] # キーが存在しない場合、新しいリストとして追加
############################################################################################################
# 重複を許した特定のキーで辞書からサーフェスIDを取得する関数
############################################################################################################
def get_random_value(self, dictionary, key):
if key in dictionary:
return int(random.choice(dictionary[key])) # ランダムに1つの値を選択
else:
return -1 # キーが存在しない場合
############################################################################################################
# 一致度の高い順位にサーフェスIDを取得する関数
############################################################################################################
def get_best_surface_id(self, charcter_id, face_name):
key = self.get_just_surface_key(charcter_id, face_name) #ぴったり一致したサーフェスID検索用のキー
tmp_surfece_id = self.get_random_value(self.dict_just_surface_id, key) #ぴったり一致したサーフェスID検索
if tmp_surfece_id >= 0: #サーフェスIDとして正しかったら関数終了
return tmp_surfece_id
key = self.get_sketchy_surface_key(charcter_id, face_name) #大体一致したサーフェスID検索用のキー
tmp_surfece_id = self.get_random_value(self.dict_sketchy_surface_id, key) #大体一致したサーフェスID検索用
if tmp_surfece_id >= 0: #サーフェスIDとして正しかったら関数終了
return tmp_surfece_id
#どうしようもないのでデフォルトID返却
if charcter_id == 0:
return 0
else:
return 10
送信メッセージも自動化しよう
キャラクターID、フォントサイズ、サーフェスID、メッセージ本文がSSTP通信の基本的な電文となります。
ページトップのような書き方して、表示タイミングを合わせるのも面倒です。
テンプレでいいじゃん。
############################################################################################################
# SSTPメッセージを制御文字列などと結合して作成する
############################################################################################################
def create_sstp_msg(self, charcter_id, face_name,font_size, msg):
if self.surface_dict is None:
#未定義の場合は読み込み
self.surface_dict = _sketchy_surface_dict()
#サーフェスIDに変換
surface_id = self.surface_dict.get_best_surface_id(charcter_id, face_name)
#charcter_id, surface_id, font_size, msgを結合してSSTP用文字列生成
sstp_msg = f"\\{charcter_id}\\f[height,{font_size}]\\s[{surface_id}]{msg}"
#生成した文字列を戻す
return sstp_msg
インスタンスを意識するのも面倒ですよね
綺麗とは言い辛いが、グローバル変数(ファイル内で使用)と関数で対応しよう。
############################################################################################################
# このファイルの中だけのグローバル変数
############################################################################################################
_send_sstp_cotroller =_send_sstp_control()
############################################################################################################
# 外部から呼び出し用のFunction
############################################################################################################
############################################################################################################
# メッセージキューにためる
############################################################################################################
def stock_talk(charcter_id, face_name, font_size, msg):
_send_sstp_cotroller.stock_talk(charcter_id, face_name, font_size, msg)
############################################################################################################
# 会話の一区切りを入れる
############################################################################################################
def break_talk():
_send_sstp_cotroller.break_talk()
############################################################################################################
# 蓄積したメッセージをSSTP送信する
############################################################################################################
def send_talk():
_send_sstp_cotroller.send_talk()
実装結果と実行結果
stock_talk(0,'落ち込み',16,'ちょうびっくりー')
stock_talk(1,'落ち込み',24,'ちょうびっくり!!!!')
stock_talk(1,'落ち込み1',16,'ほんとに??????')
stock_talk(0,'落ち込み1',24,'ほんと!')
stock_talk(1,'落ち込み2',12,'えーーーーーー!')
break_talk()
stock_talk(0,'落ち込み2',16,'えーーー')
stock_talk(0,'落ち込み3',24,'ほんと!')
stock_talk(0,'落ち込み3',24,'まじで!!')
stock_talk(0,'落ち込み4',36,'まじで!!!')
send_talk()
この呼び出しで、キャラクター割り振りと会話同期ができるようになりました。
これでメインの作業に戻れる。。。