【Ren’Py】Pythonで始めるノベルゲーム制作2 変換とスプラッシュスクリーン

専門

前回Ren’Py Launcherの導入、またドキュメントを読んで所見を書いた。

【Ren'Py】Pythonで始めるノベルゲーム制作1 導入と所見
ブログ内でのノベルゲーム制作に両足突っ込んで足湯することになったのでゲームエンジンについて調べることに。吉里吉里やティラノスクリプトも候補にあったが、自分はPythonなら書けるのと環境がLinuxであるということでRen'Pyが最有力...

今回は実際にスクリプト作業を頼まれたので、実装に伴って新しく知った機能について一部まとめることにする。

サイドイメージの表示

サイドイメージ — Ren'Py Documentation

あるキャラクターが話す時、メッセージウィンドウの左側にキャラの画像を表示させたいことが多々ある。

最初は以下のような表示であったが、物書きにサイド画像が欲しいと頼まれた。

クイサレ
クイサレ

セリフウィンドウの左側に発言者の顔を出してほしい
現状だと会話の発言者が分かりにくいと思う

対応は簡単で、キャラクター定義のオプションにimage="画像"を追加するだけだ。

image satoshi = "satoshi.png"
define sat = Character("諭", image="satoshi")

また、サイド画像を用意する必要がある。上のようにキャラ定義でimage="satoshi"とした場合は、game/imagesディレクトリにside satoshi.pngという画像を置けばよい。

sideが識別子となり自動で適用される。

画像表示の位置定義

Animation and Transformation Language (ATL) — Ren'Py Documentation

標準でleft, center, rightという位置が定義されている。

show saeko at left
show satoshi at center
show fumika at right

しかし、キャラクターを1人表示するのにcenterのみだと左右の隙間が気になる。また、2人表示するのにleft, rightを用いると中央の隙間が寂しい。

center

left, right

そこで新しく位置を定義した。gameディレクトリにtransforms.rpy(”transforms”の部分名は何でも良い)というファイルを作成し、記述していく。

今回は表示位置+表示人数を変換名にした。キャラクターの表示サイズを変えるだけで評価が変わったという話を聞いたことがあるので、人数に応じてクロッピングと拡大を行っている。

transform center1:
    xalign 0.5
    yalign 1.0
    crop_relative True
    crop (0, 0, 1, 0.9)
    zoom 1.2

transform left2:
    xalign 0.25
    yalign 1.0
    crop_relative True
    crop (0, 0, 1, 0.9)
    zoom 1.1

transform right2:
    xalign 0.75
    yalign 1.0
    crop_relative True
    crop (0, 0, 1, 0.9)
    zoom 1.1

変換は関数的に定義することもできる。汎用性の高い中央表示は以下のように定義して、ラップしても良いかもしれない。

transform Center(zoom_rate=1.0, crop_bottom=1.0):
    xalign 0.5
    yalign 1.0
    crop_relative True
    crop (0, 0, 1, crop_bottom)
    zoom zoom_rate

transform center1:
    Center(1.2, 0.9)

これで先程の表示を置換えた。

center1

left2, right2

よりキャラクターが際立つようになったと思う。

しかし、副作用としてmoveトランジェクションの利用がしづらくなるといった問題もある。moveトランジェクションは位置のみを変更するため、例えばcenter1からleftに移動するとき、画像は1.2倍に拡大されたまま移動する。

移動しながらサイズが変わるのも不自然であるため修正は行わず、積極的にdissolveトランジェクションを用いることにした。

スプラッシュスクリーンの作成

Adding a Splashscreen - Historic Ren'Py Wiki

メインメニューの表示前に制作ロゴを表示させたいという要望を受け実装することに。

パソコンの起動時にメーカーロゴが表示されるのと同じイメージで、スプラッシュスクリーンと言うらしい。

Ren’Pyでの実装ではsplashscreenという名前のラベルを作成し、そこに記述すれば自動で読み込んでくれる。

今回は他のスクリプトと分離させるためにgameディレクトリにsplashscreen.rpyというファイルを作成した。

以下のスクリプトではgame/imagesディレクトリのsplash.pngを表示させている。

splash.png

image bg white = "#fff"
image splash = "splash.png"

label splashscreen:
    scene black
    with Pause(1, hard='True')

    scene bg white with dissolve
    show splash at truecenter with dissolve
    with Pause(2, hard='True')

    scene black with dissolve
    with Pause(1, hard='True')

    return

【Web】データ読込時の画像設定

Beta版ではあるがRen’PyにはWeb上でゲームを動作させる機能がある。

しかし、起動はデータのダウンロードから始まるためPC向けに比べて時間がかかる。その間以下の画像が表示されるのだが、何か気になる。怪しい広告のような…

というわけで変更することにした。

web-presplash.png

適用方法はプロジェクトのルートディレクトリにweb-presplash.pngという画像ファイル(.jpegでも良い)を置くだけ。配置場所がgame/imagesディレクトリでないことに注意。

先程のスプラッシュスクリーンと合わせて以下のように動作する。

「 」の調整

日本語の会話文ではまず「」を用いる。しかし、これも文字のひとつとして認識されるため2行以上の文では以下のように表示される。

2行目の1文字目が から出てしまっている。DDLCの日本語翻訳版も同様だ。いくつかのノベルゲーム体験版でテキストウィンドウを確認したところ五分五分であった。

必要性と言われると優先度は低いが、Ren’Pyの学習も兼ねて対応させることにした。

まず、2行目以降にインデントを加えるrest_indentというスタイルプロパティが存在する。ちなみに1行目のインデント処理はfirst_indentで指定し、共に整数値でインデントサイズを引数にとる。

スタイルのプロパティー — Ren'Py Documentation

インデントサイズは文字サイズを参照したかったが、どれが該当するか分からなかった。style.text.sizeをインデントサイズとして指定することにしたが、文字サイズを変更したときにサイズは変更されなかった。有識者に意見を求めたいところ。

次に、テキスト表示に関してはgame/screens.rpyで制御を行っている。

100行目付近のsayスクリーン部分

これを見ると112行目のtext what id "what"という部分でテキストを受け渡していることが分かる。

今回は以下の3条件を満たすときにrest_indentプロパティを指定することにした。

  1. what(テキスト)が存在する
  2. what(テキスト)がから始まる

この仕様に則って編集を行う。

条件2はwhatがテキストタグから始まっている可能性もあるため正規表現で { }を除外する。

pythonのreモジュールを利用するため、game/init.rpy(ファイル名任意)を作成し、reモジュールを読み込んだ。

init python:
    import re

また、game/screens.rpyのsayラベルを一部編集した。

if who is not None:

    window:
        id "namebox"
        style "namebox"
        text who id "who"

if what and re.sub(r"\{[^}]*\}", "", what)[0] == "「":
    text what id "what" rest_indent style.text.size
else:
    text what id "what"

以上のカスタマイズで2行目以降の文字の に収まるようになった。

あとがき

スクリプト作業を通して基本となる機能についての理解は深まったと思う。

要望に合わせて機能を実装することは出来ても、また別の問題が発生するというパターンを繰り返しているため、解決方法を調べてスッキリさせたい。

コメント

タイトルとURLをコピーしました