【プチコン講座】メッセージイベントに変数を組み込んでみよう

プチコン

プチコン メッセージ変数

こんにちは。継続の錬金術士なおキーヌです。

ブログ毎日更新は145日目になります。

前回「【プチコン講座】メッセージ送りの実装をしてみよう」でメッセージイベントが発動した時にとまるようにしました。

現在宝箱を開けたらメッセージが固定のままなので変更しなければいけません。

メッセージを可変にする場合は、変数の組み込みが必須です。

ゲームに必要な文字列をすべて定義して配列化してしまい取り出してメッセージに組み込むという処理を学びます。

それではプチコンでRPG作り第17回目を始めましょう。

  1. ゲームのデータベースを作ろう
  2. メッセージに変数を組み込もう

ゲームのデータベースを作ろう

今回のゲームに使うデータベースを作ろうと思います。

これも本来は別データファイルにして読み込んだ方がいいのですが、
私のチュートリアルでは外部ファイル読み込みを学習していませんので、
何度も言っていますが1つのファイルに全部埋め込んでいきます。

ここでやることは変数と配列を定義して、ラベルを作りDATAでデータ内容を宣言します。

@PLAYER_INIT_STATUS
DATA 1,20,20,3,2,3,0,1

@SYSTEMWORD
DATA "STATUS", "ポーション", "ヶ", "Lv", "HP", "STR", "DEF", "AGI", "EXP", "NEXT"

@ITEMNAME
DATA "ライフポーション", "せいすい"

@ENEMYNAME
DATA "リトルバット", "ゴブリン", "スケルトン", "マミー", "ゴースト"

@MESSAGEDATA
DATA "は たからばこを あけた", "たからばこ には", "が はいっていた!"

固定データ的なものは一旦このなものですかね。

メッセージデータはバトルシーンでも追加するので、その都度追加します。

一旦これだけあればバトル開始前までは実装できそうですね。

メッセージに変数を組み込もう

このままでは何に話しかけても宝箱を開けてライフポーションをゲットしたことになっているので
先ほど作ったデータベースからデータを取ってきて、メッセージイベントに応じてメッセージ内容を変更したいと思います。

データベースから取ったデータを入れるための変数と配列を定義しましょう。

# プレイヤー用
VAR G_PLAYER_STATUS_LEN = 8
DIM G_PLAYER_STATUS[0]

# アイテム名用
VAR G_ITEMS_NAMES_LEN = 2
DIM G_ITEMS_NAMES[0]

# システムワード
VAR G_SYSTEM_WORDS_LEN = 10
DIM G_SYSTEM_WORDS[0]

# 敵用
VAR G_ENEMY_NAMES_LEN = 5
DIM G_ENEMY_NAMES[0]

# メッセージ用
VAR G_MSG_DATAS_LEN = 3
DIM G_MSG_DATAS[0]

次に、読み込むための処理を書きたいのですが、
データベースから読み込む処理って大体似たり寄ったりになっていませんか?

メッセージデータもFOR命令を使って読み込んでいましたね。

同じような処理は関数化したほうがいいので、1つにまとめてしまいましょう。

汎用性がない特殊なタイプのものは、引数の値で分岐させてあげましょう。

DEF D_DB_LOAD A_ID, A_LEN, A_ARY

  IF A_ID == 0 THEN
    VAR ARY_WORD = 0
  ELSE
    VAR ARY_WORD = ""
  ENDIF

  IF A_ID == 0 THEN
    RESTORE @PLAYER_INIT_STATUS
  ELSEIF A_ID == 1 THEN
    RESTORE @SYSTEMWORD
  ELSEIF A_ID == 2 THEN
    RESTORE @ITEMNAME
  ELSEIF A_ID == 3 THEN
    RESTORE @ENEMYNAME
  ELSEIF A_ID == 4 THEN
    RESTPRE @MESSAGEDATA
  ENDIF

  FOR G_I=0 to A_LEN-1
    READ ARY_WORD
    PUSH A_ARY, ARY_WORDS
    # 読み込み確認用
    PRINT A_ARY[G_I]
  NEXT
END

D_DB_LOADは引数に読み込む番号と配列の長さと配列そのものを渡しています。

1つ目の読み込む番号に関してはグローバル変数でこの関数を実行する度に
インクリメントをしてもよかったのですが、一応明示的に番号を指定しています。

2つ目の引数である配列の長さはこれは事前にデータ何個あるのかを数えておかなければいけません。

試しに最初に配列の大きさを決めてその配列の大きさをしていしてってやってみたのですが
どうやらPUSHでは希望通りの動きをしてくれなく手動にしました。

3つ目の配列そのものは参照渡しです。

本来、引数に渡したものはその中でしか影響を受けないのですが、参照渡しになると大元の変数にも影響を及ぼします。

ここはポインタという概念の話になってくるので、配列そのものを引数で渡すと大元に処理が反映されると思っておいてください。

この辺の参照渡しの感覚はプログラミングをしている内になんとなくつかめてきます。

予想外の動きをしている!ってなったときは大抵は参照渡しになっていると思うのでもし変な値が代入されて居たりしたら疑ってみてください。

後、最初はプレイヤーの初期ステータスを読み込むとき数値にしていますが、基本は文字列です。

定義をIDで分岐させていますがデータをPUSHする時は分岐していません。

私は個人的にサフィックス(文字列なら変数末に$をつけるやつ)を記述しているので、
最後のPUSUの部分も分岐させています。

記事に記載しているコードでエラーがでるようなら文字列と数値を明示的に切り分けてみましょう。

エラーが起って解決するのもプログラミング勉強の一環です。

それでは早速この関数を使ってデータを読み込んでみましょう。


D_DB_LOAD 0, G_PLAYER_STATUS_LEN, G_PLAYER_STATUS
D_DB_LOAD 1, G_SYSTEM_WORDS_LEN, G_SYSTEM_WORDS
D_DB_LOAD 2, G_ITEM_NAMES_LEN, G_ITEM_NAMES
D_DB_LOAD 3, G_ENEMY_NAMES_LEN, G_ENEMY_NAMES
D_DB_LOAD 4, G_MSG_DATAS_LEN, G_MSD_DATAS

実行してみてコンソールに読み込んだ文字が羅列されていれば成功です。

これでテキストデータの準備はできました。

早速メッセージを変数を組み込んだものに変更してみましょう。

メッセージを変数に置き換えてみる

イベントキュー取り出しでタイプとイベント内容と補足と3つのデータを取り出せました。

タイプはイベント分岐に使っていますので、イベントと補足の数値をメッセージウィンドウ関数に渡してしまえばメッセージを変数に置き換えられますね。

データベースで作ったメッセージ定型文と組み合わせて1つのメッセージにすることで、イベントのデータを変更すれば中身の違った宝箱イベントが作ることができます。

それでは書き換えてみましょう


DEF D_SHIFT_EV_DATA
  VAR TYPE = SHIFT(G_EV_QUEUE)
  VAR EVENT = SHIFT(G_EV_QUEUE)
  VAR RESERVE = SHIFT(G_EV_QUEUE)

  PRINT "[イベント かいし]"
  PRINT "===================="

  IF TYPE == 1 THEN
    D_WINDOW_DRAW EVENT, RESERVE
    G_EV_Q_FLAG = 1
  ELSEIF TYPE == 2 THEN
  ELSEIF TYPE == 3 THEN
  ELSEIF TYPE == 10 THEN
  ENDIF

  PRINT "-------------------"

  IF LEN(G_EV_QUEUE) <= 0 THEN
    G_SCENE_FLAG = 0
  ENDIF
END


DEF D_WINDOW_DRAW A_EVENT, A_RESERVE

  ~~~ 省略 ~~~

  # ウィンドウに文字を載せる
  GPUTCHR 85, 155, "プレイヤー" + G_MSG_DATAS[0]
  GPUTCHR 85, 165, G_MSG_DATAS[1] + G_ITEMS_NAMES[A_EVENT] + G_MSG_DATAS[2]

END

これで宝箱を開けてみてください。

ちゃんと変数を元に文字が変わっていますね。

今回は一旦これで終わります。

次回は宝箱イベントを完成させてみましょう。

現在はメッセージイベント送りはしましたが、関数で一気に文字が表示されてしまっているので
ウィンドウ生成とメッセージ表示は切り分け無ければいけません。

なので次回はメッセージ表示の修正と宝箱イベントの完成をやります。

──プチコン4になって結構命令が変わっちゃったので当講座は第一回にして壁にぶつかりました(笑)

というのも、デフォルトでマップエディタが無かったので自作するしかなかったので
プチコン4に対応した記事はまた別に書いていこうと思います。

共通する部分は同じ記事を見てください的な感じを予定しております。

最後に恒例のここまでのソースコードを張り付けておきます。

それでは。

ACLS

# 変数定義
VAR G_STOP_FLAG = TRUE # ゲームループフラグ
VAR G_SCENE_FLAG = 0 # シーンフラグ
VAR G_I # 汎用変数
VAR G_OX = 0, G_OY = 0 # BG読み込みのオフセット
VAR G_SZ=16, G_MW, G_MH # チップサイズ、マップ幅、マップ高さ
VAR G_BGW = CEIL(400/G_SZ), G_BGH = CEIL(240/G_SZ) # BG読み込み準備
DIM G_MAP[0] # マップレイヤー4枚+イベントレイヤー分

# 変数定義
VAR G_SP_PLAYER = 0 # PLAYERスプライトNo.
DIM G_SP_ANIM_NO[9] # スプライトアニメーション初期値変数 添え字=ID
DIM G_EV_ID[32] # イベント用情報の配列
VAR G_EV_STEP = 4 # 1つのイベントデータ数
DIM G_EV_QUEUE[0] # イベントキュー配列

# プレイヤー用
VAR G_PLAYER_STATUS_LEN = 8
DIM G_PLAYER_STATUS[0]

# アイテム名用
VAR G_ITEMS_NAMES_LEN = 2
DIM G_ITEMS_NAMES[0]

# システムワード
VAR G_SYSTEM_WORDS_LEN = 10
DIM G_SYSTEM_WORDS[0]

# 敵用
VAR G_ENEMY_NAMES_LEN = 5
DIM G_ENEMY_NAMES[0]

# メッセージ用
VAR G_MSG_DATAS_LEN = 3
DIM G_MSG_DATAS[0]

# ボタン分の配列を用意
DIM G_BTN_PRESS_COUNT[13]
# 一応定義したボタン配列を0で初期化しておく
FILL G_BTN_PRESS_COUNT,0

# データ定義場所
DATA 500,1040,920,1000,980,1020,269,269,269
DATA 1,5,5,2,  2,4,11,2,  3,23,13,2,  4,13,3,2,  5,22,4,2
DATA 6,6,7,1,  7,3,11,1,  8,22,3,1

@EVENT006
DATA 5,  10,10,0  3,1,1  2,1,0  1,1,0  1,2,1

@PLAYER_INIT_STATUS
DATA 1,20,20,3,2,3,0,1

@SYSTEMWORD
DATA "STATUS", "ポーション", "ヶ", "Lv", "HP", "STR", "DEF", "AGI", "EXP", "NEXT"

@ITEMDATA
DATA "ライフポーション", "せいすい"

@ENEMYNAME
DATA "リトルバット", "ゴブリン", "スケルトン", "マミー", "ゴースト"

@MESSAGEDATA
DATA "は たからばこを あけた", "たからばこ には", "が はいっていた!"



# アニメーション配列初期値代入
D_FIRST_DATA_READ G_SP_ANIM_NO
# イベントID,X座標,Y座標代入
D_FIRST_DATA_READ G_EV_ID

# マップデータ準備
LOAD "DAT:TEST", G_MAP, 0 # マップデータのロード
G_MW = SHIFT(G_MAP) # 読み込んだデータ配列の0個目を配列から切り離して取得(1638415という数字が入ってる)
G_MH = G_MW AND &HFFFF : G_MW = G_MW >> 16 AND &HFFFF # 取り出したデータからシフト演算やらビット演算をする

# マップデータ描写
FOR G_I=0 TO 3
  BGSCREEN G_I, G_BGW, G_BGH, G_SZ # 1画面分のBG
  BGOFS 0,0,4-G_I
  BGLOAD I, -G_OX, ( -G_OY - ( G_I * G_MH )), G_MW, G_MH * ( G_I + 1 ), G_MAP # マップ描写
NEXT

# プレイヤー配置
D_SP_SETUP G_SP_PLAYER, 1, 0

# イベント配置
FOR G_I=0 TO LEN(G_EV_ID)-1 STEP G_EV_STEP
  D_SP_SETUP G_EV_ID[G_I], G_EV_ID[G_I+1], EV_ID[G_I+2]
NEXT

# 各種データの読み込み
D_DB_LOAD 0, G_PLAYER_STATUS_LEN, G_PLAYER_STATUS
D_DB_LOAD 1, G_SYSTEM_WORDS_LEN, G_SYSTEM_WORDS
D_DB_LOAD 2, G_ITEM_NAMES_LEN, G_ITEM_NAMES
D_DB_LOAD 3, G_ENEMY_NAMES_LEN, G_ENEMY_NAMES
D_DB_LOAD 4, G_MSG_DATAS_LEN, G_MSD_DATAS

# グラフィックでウィンドウを定義
GPRIO 0

# ゲームループ
WHILE G_STOP_FLAG
  D_SCENE_PARENT
  VSYNC 1
WEND

# シーンの大元
DEF SCENE_PARENT

  IF G_SCENE_FLAG == 0 THEN
    D_CTRL_MAP_MODE
  ELSEIF G_SCENE_FLAG == 1 THEN
    IF G_EV_Q_FLAG == 0 THEN
      D_SHIFT_EV_DATA
    ELSEIF EV_Q_FLAG == 1 THEN
      D_EV_STOP_A_BTN
    ENDIF
  ENDIF

  D_BTN_PRESS

END

# マップ用コントローラー関数
DEF D_CTRL_MAP_MODE
  IF SPVAR(SP_PLAYER, 2) != 1 THEN
    VAR B = BUTTON()
    IF (B AND #UP) > 0 THEN
      IF D_CHECK_COLLISION(G_SP_PLAYER, #UP) == 1 THEN
        D_DIRECTION_MOVE SP_PLAYER, #UP
      ENDIF
    ELSEIF (B AND #DOWN) > 0 THEN
      IF D_CHECK_COLLISION(G_SP_PLAYER, #DOWN) == 1 THEN
        D_DIRECTION_MOVE SP_PLAYER, #DOWN
      ENDIF
    ELSEIF (B AND #LEFT) > 0 THEN
      IF D_CHECK_COLLISION(G_SP_PLAYER, #LEFT) == 1 THEN
        D_DIRECTION_MOVE SP_PLAYER, #LEFT
      ENDIF
    ELSEIF (B AND #RIGHT) > 0 THEN
      IF D_CHECK_COLLISION(G_SP_PLAYER, #RIGHT) == 1 THEN
        D_DIRECTION_MOVE SP_PLAYER, #RIGHT
      ENDIF
    ENDIF
  ELSE
    D_GRID_MOVE SP_PLAYER, (SPVAR SP_PLAYER, 3)
  ENDIF

  # 移動中もボタンを押せるようにしておく
  IF G_BTN_PRESS_COUNT[4] == 1 THEN
    PRINT "Aボタンが押されたよ!"
    D_EV_CHECK G_SP_PLAYER SPVAR(G_SP_PLAYER, 3)
  ENDIF

  IF G_BTN_PRESS_COUNT[6] == 1 THEN
    PRINT "Xボタンが押されたよ!"
  ENDIF
END


# 向きと移動フラグを設定
DEF D_DIRECTION_MOVE A_SPRITE_NO, A_SPRITE_DIRECTION
  SPVAR A_SPRITE_NO, 2, 1
  SPVAR A_SPRITE_NO, 3, A_DIRECTION
END

# 向いている方向に止まるまで歩き続ける(グリッド移動)
DEF D_GRID_MOVE SPRITE_NO, SPRITE_DIRECTION
  # 渡されたスプライトと向きによって移動方向を決定
  IF SPRITE_DIRECTION == #UP THEN
    SPVAR SPRITE_NO, 1, (SPVAR SPRITE_NO, 1) - 1
  ELSEIF SPRITE_DIRECTION == #DOWN THEN
    SPVAR SPRITE_NO, 1, (SPVAR SPRITE_NO, 1) + 1
  ELSEIF SPRITE_DIRECTION == #LEFT THEN
    SPVAR SPRITE_NO, 0, (SPVAR SPRITE_NO, 0) - 1
  ELSEIF SPRITE_DIRECTION == #RIGHT THEN
    SPVAR SPRITE_NO, 0, (SPVAR SPRITE_NO, 0) + 1
  ENDIF

  # 移動させる
  SPOFS SPRITE_NO,(SPVAR SPRITE_NO, 0),(SPVAR SPRITE_NO, 1)

  # 割った余りが0になったら動きを止める
  IF (SPVAR SPRITE_NO, 0) MOD G_SZ == 0 && (SPVAR G_SPRITE_NO, 1) MOD G_SZ == 0 THEN
    SPVAR G_SPRITE_NO, 2, 0
  ENDIF

END

# ドット座標からグリッド座標に変換
DEF D_GET_GRID_XY(A_X_OR_Y)
  RETURN A_X_OR_Y / G_SZ
END

# MAP配列のどこにいるかチェック
DEF D_GET_MAP_POSITION(A_X, A_Y, A_LAYER)
  VAR RETURN_POS = 0
  VAR GRID_X = D_GET_GRID_XY(A_X)
  VAR GRID_Y = D_GET_GRID_XY(A_Y)

  VAR PULS_LAYER = (G_MW * G_MH) * A_LAYER

  IF A_Y <= 0 THEN
    RETURN_POS = GRID_X + PLUS_LAYER
  ELSE
    RETURN_POS = (GRID_X + (GRID_Y * G_MW)) + PLUS_LAYER
  ENDIF

  RETURN RETURN_POS
END

# 当たり判定チェック
DEF D_CHECK_COLLISION(A_NO, A_DIRECTION)
  VAR MP1_SUM_POS = 0
  VAR EV_SUM_POS = 0

  VAR DIRECT = D_GET_DIRECT_POINT(A_DIRECTION)

  VAR MAP_POS = D_GET_MAP_POSITION(SPVAR(A_NO,0), SPVAR(A_NO,1), 1)
  VAR EVENT_POS = D_GET_MAP_POSITION(SPVAR(A_NO,0), SPVAR(A_NO,1), 3)

  MP1_SUM_POS = MAP_POS + DIRECT
  EV_SUM_POS = EVENT_POS + DIRECT

  IF G_MAP[MP1_SUM_POS] == 0 THEN
    IF G_MAP[EV_SUM_POS] == 0 THEN
      D_EV_LAYER_REWRITE A_NO, A_DIRECTION, 1
      RETURN 1
    ELSE
      RETURN
    ENDIF
  ELSE
    RETURN 0
  ENDIF
END

# スプライトセットアップ
DEF D_SP_SETUP A_NO, A_X, A_Y
  VAR F = 20
  VAR ANIM = G_SP_ANIM_NO[A_NO]

  SPSET A_NO ANIM
  SPVAR A_NO 0, G_SZ * A_X
  SPVAR A_NO 1, G_SZ * A_Y
  SPVAR A_NO 2, 0
  SPVAR A_NO 3, #DOWN
  SPOFS A_NO SPVAR(A_NO,0), SPVAR(A_NO,1),1

  IF A_NO == 0 || G_EV_ID[(G_EV_STEP * A_NO)-1] == 2 THEN
    SPANIM A_NO, "I", F,ANIM, F,ANIM+1, F,ANIM+2, F,ANIM+3, 0 
  ENDIF
END

# イベントレイヤー書き換え
DEF D_EV_LAYER_REWRITE A_NO, A_DIRECT, A_FLAG

  VAR POS = D_GET_MAP_POSITION(SPVAR(A_NO,0), SPVAR(A_NO,1), 3)

  IF A_FLAG > 0 THEN
    IF A_DIRECT > 0 THEN
      VAR AFTER_POS = POS + D_GET_DIRECT_POINT(A_DIRECT)
      G_MAP[AFTER_POS] = A_NO
    ELSE
      G_MAP[POS] = A_NO
    ENDIF
  ELSE
    VAR BEFORE_POS = POS - D_GET_DIRECT_POINT(A_DIRECT)
    G_MAP[BEFORE_POS] = 0
  ENDIF

END

# 方向定数から1歩前のグリッド座標を得るための値を得る
DEF D_GET_DIRECT_POINT(A_DIRECTION)
  IF A_DIRECTION == #UP THEN
    RETURN DIRECT = -MW
  ELSEIF A_DIRECTION == #DOWN THEN
    RETURN DIRECT = MW
  ELSEIF A_DIRECTION == #LEFT THEN
    RETURN DIRECT = -1
  ELSEIF A_DIRECTION == #RIGHT THEN
    RETURN DIRECT = 1
  ENDIF
END

# DATA初期読み込み
DEF DD_FIRST_DATA_READ A_ARRAY
  FOR G_I=0 TO LEN(G_EV_ID)-1
    VAR N=0: READ N
    G_EV_ID[G_I] = N
  NEXT
END

# ボタンカウント関数
DEF D_BTN_PRESS_COUNT
  VAR B = BUTTON()

  # Aボタンカウント
  IF (B AND #A) > 0 THEN
    IF G_BTN_PRESS_COUNT[4] < 255 THEN 
      INC G_BTN_PRESS_COUNT[4]
    ENDIF
  ELSE
    # 1回でも離されたらカウントリセット
    G_BTN_PRESS_COUNT[4] = 0
  ENDIF

  # Xボタンカウント
  IF (B AND #X) > 0 THEN
    IF G_BTN_PRESS_COUNT[6] < 255 THEN 
      INC G_BTN_PRESS_COUNT[6]
    ENDIF
  ELSE
    # 1回でも離されたらカウントリセット
    G_BTN_PRESS_COUNT[6] = 0
  ENDIF

END

# 前方のイベントをチェックする
DEF D_EV_CHECK A_NO A_DIRECT

  VAR POS = D_GET_MAP_POSITION(SPVAR(A_NO,0), SPVAR(A_NO,1), 3)
  VAR AFTER_POS = POS + D_GET_DIRECT_POINT(A_DIRECT)

  VAR EV_ID = G_MAP[AFTER_POS]

 D_GET_EV_DATA EV_ID
END

# イベントリストからイベントキューへ挿入
DEF D_GET_EV_DATA A_ID
  VAR EV_COUNT = 0
  VAR EV_DATA = 0

  IF A_ID == 6 THEN
    RESTORE @EVENT006
    READ EV_COUNT
    FOR G_I=1 TO (EV_COUNT * 3)-1
      READ EV_DATA
      PUSH G_EV_QUEUE, EV_DATA
    NEXT
  ENDIF

  IF LEN(G_EV_QUEUE) > 0 THEN
    G_SCENE_FLAG = 1
  ENDIF
END

DEF D_SHIFT_EV_DATA
  VAR TYPE = SHIFT(G_EV_QUEUE)
  VAR EVENT = SHIFT(G_EV_QUEUE)
  VAR RESERVE = SHIFT(G_EV_QUEUE)

  PRINT "[イベント かいし]"
  PRINT "===================="

  IF TYPE == 1 THEN
    D_WINDOW_DRAW EVENT, RESERVE
    G_EV_Q_FLAG = 1
  ELSEIF TYPE == 2 THEN
  ELSEIF TYPE == 3 THEN
  ELSEIF TYPE == 10 THEN
  ENDIF

  PRINT "-------------------"

  IF LEN(G_EV_QUEUE) <= 0 THEN
    G_SCENE_FLAG = 0
  ENDIF
END



DEF D_WINDOW_DRAW A_EVENT, A_RESERVE
  GFILL 80, 150, 320, 208 RGB(0, 21, 151)

  GBOX 79, 149, 321, 209, RGB(128,126,129)
  GBOX 78, 148, 322, 210, RGB(128,126,129)
  GBOX 77, 147, 323, 211, RGB(128,126,129)

  GPSET 78, 148,  RGB(255,255,255)
  GPSET 78, 210,  RGB(255,255,255)
  GPSET 322, 148,  RGB(255,255,255)
  GPSET 322, 210,  RGB(255,255,255)

  GLINE 77, 149, 77, 209, RGB(255,255,255)
  GLINE 76, 149, 76, 209,  RGB(128,126,129)

  GLINE 323, 149, 323, 209, RGB(255,255,255)
  GLINE 324, 149, 324, 209,  RGB(128,126,129)

  GLINE 79, 147, 321, 147, RGB(255,255,255)
  GLINE 79, 146, 321, 146, RGB(128,126,129)

  GLINE 79, 211, 321, 211, RGB(255,255,255)
  GLINE 79, 212, 321, 212, RGB(128,126,129)




  # ウィンドウに文字を載せる
  GPUTCHR 85, 155, "プレイヤー" + G_MSG_DATAS[0]
  GPUTCHR 85, 165, G_MSG_DATAS[1] + G_ITEMS_NAMES[A_EVENT] + G_MSG_DATAS[2]

END

DEF D_EV_STOP_A_BTN
  IF G_BTN_PRESS_COUNT[4] == 1 THEN
    PRINT "メッセージ待機解除"
    G_EV_Q_FLAG = 0
  ENDIF
END


DEF D_DB_LOAD A_ID, A_LEN, A_ARY

  IF A_ID == 0 THEN
    VAR ARY_WORD = 0
  ELSE
    VAR ARY_WORD = ""
  ENDIF

  IF A_ID == 0 THEN
    RESTORE @PLAYER_INIT_STATUS
  ELSEIF A_ID == 1 THEN
    RESTORE @SYSTEMWORD
  ELSEIF A_ID == 2 THEN
    RESTORE @ITEMNAME
  ELSEIF A_ID == 3 THEN
    RESTORE @ENEMYNAME
  ELSEIF A_ID == 4 THEN
    RESTPRE @MESSAGEDATA
  ENDIF

  FOR G_I=0 to A_LEN-1
    READ ARY_WORD
    PUSH A_ARY, ARY_WORDS
    # 読み込み確認用
    PRINT A_ARY[G_I]
  NEXT
END