【ティラノスクリプト】イベントCG表示時にカットイン表示切り替え

# イベントCGを表示しているときにカットイン画像を表示させたい
まあタイトルそのままなんですが。
現在制作しているゲームで、このような要件が発生しました。

* イベントCGを表示させるときにカットイン画像を同時に表示させたい
* カットインはユーザー側で表示・非表示を切り替えられるようにしたい
* 表示・非表示の切り替えは、イベントCG表示時の画面上とコンフィグ画面の両方で行えるようにしたい
* 画面上での表示切り替えはボタンで行う。ボタンは、カットイン表示・非表示の２つを並べるのではなく、１つのボタンをクリックすることで表示・非表示が切り替えられるようにしたい。

というわけで実装していきますが、その前に前提情報があります。

## ティラノスクリプトで`[sleepgame]`→`[awakegame]`でゲームに戻るときはロードが行われる
ティラノスクリプトでコンフィグ画面などを表示させるときは一般的に`[sleepgame]`でゲームの状態を保存し、その後コンフィグ画面でなんやかんやの処理を行い、`[awakegame]`でゲームに復帰します。
今回初めて知ったんですが、`[sleepgame]`タグを実行した時点で一度セーブが行われます（セーブスロットには保存されない）。
その後、`[awakegame]`実行時に前述のセーブデータをロードして、ゲームの状態を復帰させているようです。
ロード処理が行われるので、`[awakegame]`を実行した時点で**それ以前の一時変数はすべて破棄される**し、**`make.ks`がcallされます**。

という情報を前提に、実装していきます。

## 実装しました
~~そろそろ身バレしそうな気がしてきたぞ…~~
タイトルではカットイン画像の表示切替としていますが、実際にはカットイン以外に擬音の表示切替も行っています。~~（エロゲーだからね）~~
なので正しくは、カットイン画像および擬音画像の表示切替となります。

### ボタンの切り替え
こちらは[ティラノスクリプト非公式wiki](http://tyrano.wiki.fc2.com/wiki/%E3%83%9C%E3%82%BF%E3%83%B3%E8%A1%A8%E7%A4%BA)の「fixボタンのオンオフボタン」を参考にしました。

```eventcg.ks
;スチル用ボタン配置、スチル表示切替
*toggle_cutin
[iscript]
if(f.is_cutin === true){
    tf.btn_cutin = "button/cutin_on.png"
}else{
    tf.btn_cutin = "button/cutin_off.png"
}
[endscript]
[set_cutin]
[clearfix name="btn_is_cutin"]
[button_ad graphic="&tf.btn_cutin" fix="true" name="btn_is_cutin" auto_next="false" exp="f.is_cutin=!(f.is_cutin)" width="116" height="30" storage="system/eventcg.ks" target="*toggle_cutin" x=30 y=0]
[return]

*toggle_sound
[iscript]
if(f.is_gion === true){
    tf.btn_se = "button/sound_on.png"
}else{
    tf.btn_se = "button/sound_off.png"
}
[endscript]
[set_gion]
[clearfix name="btn_is_se"]
[button_ad graphic="&tf.btn_se" fix="true" name="btn_is_se" auto_next="false" exp="f.is_gion=!(f.is_gion)" width="116" height="30" storage="system/eventcg.ks" target="*toggle_sound" x=160 y=0]
[return]
```

で、実際にボタン（とイベントCG等）を表示させるときはこんな感じ

```scene1.ks
[call storage="eventcg.ks" target="*toggle_cutin"]
[call storage="eventcg.ks" target="*toggle_sound"]

[bg storage="event.png" time="100"]
[image storage="cutin.png" layer="1" name="event-cg-cutin" time="100" visible="true"]
[image storage="gion.png" layer="1" name="event-cg-gion" time="100" visible="true"]
[image storage="gion_cutin.png" layer="1" name="event-cg-gioncutin" time="100" visible="true"]
```

### CSSの設定
手軽に実装するならカットインと擬音それぞれを表示するレイヤーを用意してやって、`[layopt]`タグで表示切替させる、となるのでしょうけども、今回は「カットイン画像」「擬音画像」「カットイン上の擬音画像」の３種類を表示切替させることになるので、あんまりレイヤー増やすのもなあ…と思ってレイヤーは１枚にして、その中で３種類の画像それぞれに`name`属性を与えて操作することにしました。
以下のコードは、`first.ks`で読み込むことで、`<head>`内に`<style>`タグを追加し、３つの画像用クラスの`display`属性をセットしています。

```eventcg.ks
[iscript]
if($.find("#event-cg-switch").length === 0){
    $("<style id='event-cg-switch'></style>").appendTo("head")
}
var isCutIn = (f.is_cutin ? "" : "none")
var isGion = (f.is_gion ? "" : "none")
var isCutInGion = (f.is_cutin && f.is_gion ? "" : "none")
var csslist = document.styleSheets
for(i = 0; i < csslist.length; i++){
    if(csslist[i].ownerNode.id === "event-cg-switch"){
        var cssCutIn = ".event-cg-cutin{ "
        cssCutIn += " display: " + isCutIn
        cssCutIn += " } "
        var cssGion = ".event-cg-gion{ "
        cssGion += " display: " + isGion
        cssGion += " } "
        var cssCutInGion = ".event-cg-cutingion{ "
        cssCutInGion += " display: " + isCutInGion
        cssCutInGion += " } "
        $("#event-cg-switch").html(cssCutIn + cssGion + cssCutInGion)
    }
}
[endscript]
```

さらに画像表示切替ボタンをクリックしたときの処理（ボタン画像切り替え処理中の`[set_cutin]`、`[set_gion]`）は以下のような感じ

```eventcg.ks
[macro name="set_cutin"]
[iscript]
var isCutIn = (f.is_cutin ? "" : "none")
var isCutInGion = (f.is_cutin && f.is_gion ? "" : "none")
var csslist = document.styleSheets
for(i = 0; i < csslist.length; i++){
    if(csslist[i].ownerNode.id === "event-cg-switch"){
        var rule = csslist[i].cssRules
        for(j = 0; j < rule.length; j++){
            if(rule[j].selectorText === ".event-cg-cutin"){
                rule[j].style.display = isCutIn
            }else if(rule[j].selectorText === ".event-cg-cutingion"){
                rule[j].style.display = isCutInGion
            }
        }
    }
}
[endscript]
[endmacro]

[macro name="set_gion"]
[iscript]
var isGion = (f.is_Gion ? "" : "none")
var isCutInGion = (f.is_cutin && f.is_gion ? "" : "none")
var csslist = document.styleSheets
for(i = 0; i < csslist.length; i++){
    if(csslist[i].ownerNode.id === "event-cg-switch"){
        var rule = csslist[i].cssRules
        for(j = 0; j < rule.length; j++){
            if(rule[j].selectorText === ".event-cg-gion"){
                rule[j].style.display = isGion
            }else if(rule[j].selectorText === ".event-cg-cutingion"){
                rule[j].style.display = isCutInGion
            }
        }
    }
}
[endscript]
[endmacro]
```

これでイベントCG上のボタンをクリックしてのカットイン画像の表示切替はできました。
ただ、これだけではコンフィグ画面から表示を切り替えたときに、カットイン画像は切り替えられてもボタンの画像が切り替えられません。
ここで前述の、**`「[sleepgame]`、`[awakegame]`実行時はセーブ・ロード処理が行われる」**ということを思い出してください。そう、`make.ks`です。

```make.ks
;カットイン・擬音表示ボタン画像切り替え
[iscript]
if($.find(".btn_is_cutin").length > 0){
    var imgc = $(".btn_is_cutin")
    var imgg = $(".btn_is_se")
    var srcc = ""
    var srcg = ""
    if(f.is_cutin === true){
        srcc = "/data/image/button/cutin_on.png"
    }else{
        srcc = "/data/image/button/cutin_off.png"
    }
    if(f.is_gion === true){
        srcg = "/data/image/button/sound_on.png"
    }else{
        srcg = "/data/image/button/sound_off.png"
    }
    imgc.attr("data-src", srcc)
    imgc.css("background-image", "url(" + srcc + ")")
    imgg.attr("data-src", srcg)
    imgg.css("background-image", "url(" + srcg + ")")
}
[endscript]
```

こんな感じに書くことで、ロード処理時点のカットイン画像表示フラグを参照してボタンの画像を切り替えることができます。

できたらプラグイン化したかったけどちょっと難しそうだなぁ
よかったら何か参考にしてください。