本シリーズでは、Ren'Pyユーザーが知っておきたいPythonの使い方をご紹介しています。
詳細および事前準備などは「00.はじめに」をご確認ください。
今回は「ループ(for文)」の紹介です。同じ内容や、同じ形式の内容を繰り返す際に使用します。プログラミング自体では出番が多いので覚えておいて損は無いはずです。ビジュアルノベルの制作に於いては、リスト(05・06参照)とセットでスクリーン(※)の作成に役立ちます。
(※メニューなどを表示させるためのRen'Pyの機能)
準備
今回はコンソールではなくRen'Pyスクリプトで説明を進めます。
今回の記事で出てくるスクリプトのスクリーンショットは、テキストエディター「Atom」を使用した場合の表示となります。同様にAtomを使用したい方は、ランチャーの右下「設定」→「テキストエディター」で「Atom」を選択しておいてください(下図参照)。
※本記事の時点ではAtomを使用していますが、現在はVisual Studio Code推奨です(2023年1月追記)
また、スクリプトの起動時にはランチャーから「script.rpy」を選択してください。上記で設定したエディターで開くことができます。
それでは、始めましょう。
ループ(for文)の使用例
1つ簡単なサンプルスクリプトを用意しました。
プロジェクトを起動すると次のようなゲームが走ります。
(※背景画像は適当に作成しました)
「もうかりまっか」「ぼちぼちでんな」が3回くり返されます。
先ほどのゲームは次のようなスクリプトで走っています。
ポイントは太字の部分です。この後詳しく解説します。
define e = Character("エイリーン", color="#c8ffc8")
label start:
scene bg sky # (背景を表示)
with dissolve
e "サンプル開始"
python:
for i in range(0,3):
e("もうかりまっか?")
e("ぼちぼちでんな")
e "サンプル終了"
return
cf. Atom上での表示
Ren'PyにPythonコードを挿入する
ループ(for文)の説明の前に1点注意事項があります。
今回Ren'Pyスクリプトの中にPythonコードを挿入することになりますが、そのままでは挿入できません。
Ren'PyスクリプトにPythonコードを挿入するとき、1行だけなら、頭に「$」を付ければOKですが(04.条件分岐(if文)の中盤で説明済)、複数行の場合はPythonステートメントを使用します。
次の図のように使用します。
「python:」と記入し、次の行からインデントを1つ下げて任意のPythonコードを入力します。
尚、今回の例ではPythonステートメント内で
e("もうかりまっか?")
と書いていますが、これは通常のRen'Pyスクリプト(Pythonステートメントの外)で
e "もうかりまっか?"
と書くのと同じ意味です。
通常のRen'Pyスクリプト内で使用している機能をPythonステートメント内で使用する場合の記述方法は公式ドキュメント内「ステートメントの等価性」の項に記載があります。
ループ(for文)の書き方
いよいよ本題です。
for文は、同じような内容や似たような内容を繰り返す際に使用します。
今回の例であれば、下図の左の内容をfor文でまとめたのが右のコードとなります。
for文は次の図のように使用します。
「for i in range(0,3):」と入力したあと、インデントを下げて繰り返したい内容を記入します。
「range(0,3)」の「3」の部分がくり返し回数となります。厳密な説明ではありませんが、ここではそう考えておいてください。
インデント・コロンの漏れに注意してください。
練習
次のサンプルスクリプトをscript.rpyに入力し、プロジェクトを起動してみてください。
「for i in range(0,3):」の「3」の部分を4や5に変更してプロジェクトを再起動し、挙動の変化を確認してみてください。
※script.rpyに既に記入されているスクリプトがあれば削除またはコメントアウトしてください
define e = Character("エイリーン", color="#c8ffc8")
label start:
e "サンプル開始"
python:
for i in range(0,3):
e("もうかりまっか?")
e("ぼちぼちでんな")
e "サンプル終了"
return
ここまでがfor文の基本でした。
上記はあくまでfor文を極力シンプルに説明するために用意した例であり、実際に上記のようなfor文の使い方をすることは稀です。次のセクションから実用的な例を紹介します。
実践例:for文をスクリーン内で使用する
本記事をご覧の皆様はRen'Pyの「スクリーン」を使用したことがありますでしょうか。スクリーンは主にメニュー画面などを作る機能であり、デフォルトのスタートメニューやメッセージウィンドウ等もスクリーンとして定義されています。
ここからの説明では、簡単なスクリーンを用意しその中でfor文を使用します。
尚、ここからは05.リスト・06.リストの有効活用で扱った内容を含みますので、未読の方は予めご確認ください。
それでは参ります。
まず、for文とリストを組み合わせて次のようなキャラクター紹介用のスクリーン作成してみます。
上記のスクリーンを表示するための変数・スクリーン・startラベルのスクリプトです。
お手元のscript.rpyにコピー&ペーストして試してみてください。
※script.rpyに既に記入されているスクリプトがあれば削除またはコメントアウトしてください
※スクリーン内に限りfor文を直接使用することができます(Pythonステートメントに入れる必要がありません)
# 変数の設定
init python:
chara_name = ['ノーラ', 'シャイン', 'ユリアナ']
chara_intro = []
chara_intro.append('良家のご令嬢。花の世話が好きで、週末は庭師を手伝うこともある。')
chara_intro.append('王国の第五王子。手作りの王冠をいつも身に着けており、毎日手入れは欠かさない。')
chara_intro.append('良家のご令嬢。通称、聖女様。なかなか話を聞いてもらえない。')
# スクリーン
screen sample_screen():
vbox:
xalign 0.5 yalign 0.5
spacing 12
for i in range(0,len(chara_name)):
frame:
xsize 720
vbox:
text chara_name[i]
text chara_intro[i]
# startラベル
label start:
scene bg sky # 背景を表示
with dissolve
show screen sample_screen() # スクリーンの表示
with dissolve
pause
return
cf. Atom上での表示
それでは、上記のサンプルスクリプトの中身を解説していきます。
スクリーンの部分に注目します。図中の①・②の部分について解説します。
①「 len() 」について
「 len() 」はカッコ内に入れた変数の要素の数を返します。
今回の例であれば
chara_name = ['ノーラ', 'シャイン', 'ユリアナ']
のようにchara_nameに3つの要素が入っていますので
len(chara_name)
の値は「3」となります。
つまり、今回の場合は
for i in range(0,len(chara_name)):
は
for i in range(0,3):
と等価です。前半で出てきたコードと同じ形ですね。
②「 i 」について
「 i 」には自動的に数字が入ります。
「 for i 」の後、今回のように「in range(0,3)」と続いていれば
ループの1週目のときは「 i = 0 」
ループの2週目のときは「 i = 1 」
ループの3週目のときは「 i = 2 」
となります。ですので、
1つ目のフレームにはchara_name[0]とchara_intro[0]の内容
2つ目のフレームにはchara_name[1]とchara_intro[1]の内容
3つ目のフレームにはchara_name[2]とchara_intro[2]の内容
が入ります。
改めてスクリーンを見てみましょう。何となくご理解いただけましたでしょうか。
※ 冒頭の「init python:」について
サンプルスクリプトの最初に次のような記載があります。
# 変数の設定
init python:
chara_name = ['ノーラ', 'シャイン', 'ユリアナ']
chara_intro = []
chara_intro.append('良家のご令嬢。花の世話が好きで(略)')
chara_intro.append('王国の第五王子。手作りの王冠を(略)')
chara_intro.append('良家のご令嬢。通称、聖女様。なかなか(略)')
ここで登場する「init python:」も、前述の「python:」と同様にRen'Py内でPythonコードを記入するブロック(Pythonステートメント)です。但し「init」という接頭辞があることでゲーム起動時に読み込まれます。
最後に。
上記のスクリーンをもう少し作りこむと次のような形になります。
こちらのサンプルスクリプトはこの後の補足コーナーに掲載しますので、興味のある方はご覧ください。
今回はここまでです。長くなってしまいましたが、ここまで大変お疲れ様でした。
cf. 関連ページ
Ren'Py部屋 @crAsmビジュアルノベル情報部屋
お問合せフォーム - ご質問・ご要望はこちら
補足
上記で紹介したスクリーンのコードを以下に掲載します。
尚、次のような画像を用意して使用しています。
コード:
# 変数の定義
init python:
chara_name = ['ノーラ', 'シャイン', 'ユリアナ']
chara_name_e = ['nora', 'shine', 'juliana']
chara_color = ['#ccaaff', '#f0e678', '#ffbb88']
chara_intro = [] # 変数に空のリスト[]を与える
chara_intro.append('良家のご令嬢。花の世話が好きで、週末は庭師を手伝うこともある。')
chara_intro.append('王国の第五王子。手作りの王冠をいつも身に着けており、毎日手入れは欠かさない。')
chara_intro.append('良家のご令嬢。通称、聖女様。なかなか話を聞いてもらえない。')
# スクリーン
screen sample_screen():
vbox:
xalign 0.5 yalign 0.5
spacing 12
for i in range(0,len(chara_name)):
frame:
xsize 720
xpadding 48 ypadding 24
hbox:
yalign 0.5
add "images/" + chara_name_e[i] + ".png":
zoom 0.5
yalign 0.5
null width 24
vbox:
yalign 0.5
$ color_tmp = chara_color[i]
text "{color=[color_tmp]}" + chara_name[i] + "{/color}"
null height 12
text chara_intro[i]
# startラベル
label start:
scene bg sky # 背景を表示
with dissolve
show screen sample_screen() # スクリーンを表示
with dissolve
pause
return
cf. Atom上での表示
※注記)
add "images/" + chara_name_e[i] + ".png":
の部分は
add chara_name_e[i]:
とすることも可能ですが、ここでは画像のパスを明確にするために敢えて前者の形で書いています。
Ren'Pyのスクリーン言語に関する説明はここでは割愛しますが、
Ren'Pyチュートリアルの「スクリーンDisplayable」(メニューの下の方にあります)
→「ボックスとその他のレイアウト」「ウィンドウとフレーム」
やその周辺にある項目が参考になるはずです。
※ v7.4以降チュートリアルに日本語翻訳がついています
(チュートリアルを起動 → Preferences → Language から「日本語」を選択)