フワフワソが「ソラとピヨちゃん」や「宮本県」を作るブログ(フワフワソ・ラウンジnew!)

ラノベとテクノを愛するふわふわがノベルゲームを作っています。あと日常のことやイベントの告知なども。スクリプト関連の記事は自分用の備忘録です

ティラノスクリプトで小数点以下を扱う。四捨五入など

ダメージ計算などで 1*1.2 などの計算をした場合、1.2が表示されるのではなく、

浮動小数点のせいで1.2に近いすごい桁数の1.2000000~という小数点以下が表示されてしまいます。

ゲームで扱うには小数点以下を四捨五入なり切り捨てなりして、1.2などの分かりやすい桁数にしたいところです。

wikiなどをざっと拝見した感じでは、小数点以下を切り捨てして1などにする方法(javascriptのMath.floorを使う)はあるのですが、小数点以下を何桁か使って1.2や1.20などにする方法がよく分かりません。

 

javascriptを調べました。

 .toFixed()を使う方法。四捨五入して、()内の数で桁数をそろえます。

[eval exp="f.number = 17.2545"]
[iscript]
f.number = f.number.toFixed(1)
[endscript]

[emb exp=f.number]

この方法は、桁数が指定なので0が0.0などになります。 0を0にしたい場合は、以下のMath.roundを使います。

 

Math.roundを使う方法

四捨五入して、桁数をそろえます。 

[eval exp="f.number = 17.2545"]
[iscript]
f.number = Math.round(f.number * 10) / 10
[endscript]

[emb exp=f.number]

Math.round(f.number * 10) / 10のところをMath.round(f.number * 100) / 100にすると小数点以下の桁数が増えます。

Math.round(f.number)で1の位で四捨五入。

Math.round(f.number / 10) * 10で、10の位で四捨五入

 

その他。Math.ceilで切り上げ

[eval exp="f.number = 17.2545"]
[iscript]
f.number = Math.ceil(f.number * 10) / 10
[endscript]

[emb exp=f.number]

Math.floorで切り捨て

[eval exp="f.number = 17.2545"]
[iscript]
f.number = Math.floor(f.number * 10) / 10
[endscript]

[emb exp=f.number]

なお、自分はjavascriptは詳しくないので、この記事のスクリプトは正しいのかどうかは分かりません。

一応動きますが、完全に自分用の備忘録です。ご注意ください。

 

 

キーフレームアニメでイージングを自作する

RPGでよくあるダメージ表示をしたいなと思いました。

敵を殴るとダメージ数値が出てバウンドして消えるあれです。

まずキーフレームアニメでやろうと思いました。

kopacurve.blog.fc2.comこ・ぱんだ様のプラグインがとても便利なので、そういう動きがあるかなと思ったのですが、ないようです。

ソースを拝見すると改造OKと書いてありましたので、このプラグインをもとに改造させていただくことにしました。ありがとうございます。

作ったのがこちら。

[keyframe name="float_ability"]
[frame p=" 0%" y=" 0"]
[frame p="100%" y="-100"]
[endkeyframe]

 

[macro name="ability"]
[eval exp="mp.layer = '0'" cond="mp.layer == undefined"]
[eval exp="mp.time = 1500" cond="mp.time == undefined"]
[kanim name="&mp.name" layer="&mp.layer" keyframe="float_ability" easing="cubic-bezier(.38,1.37,.99,1.09)" time="&mp.time" count="1"]
[layopt layer="&mp.layer" visible="true"]
[endmacro]

キーフレーム名が float_ability

マクロ名がabilityです。

上記の設定をしてから、

[ptext layer=11 text="test" x=360 y=360 size=100 name="abilitypt" time=0 wait=false]

[ability layer=11 name="abilitypt" time=300]

このように記述すると、レイヤー11でabilityptという名前を付けたptextの文字が300ミリ秒でアニメします。

 

 ポイントはまずここ。

[frame p=" 0%" y=" 0"]
[frame p="100%" y="-100"]

キーフレームアニメの設定のところで、時間経過100%(この場合はマクロで設定した300ミリ秒)のところで、y方向に-100ピクセル移動、としておきます。とても単純です。

次に、バウンドしたりする複雑な動きは、マクロの方のeaseの設定でやります。

[kanim name="&mp.name" layer="&mp.layer" keyframe="float_ability" easing="cubic-bezier(.38,1.37,.99,1.09)" time="&mp.time" count="1"]

kanimにはeaseの設定があって、これで結構複雑な動きができると思いました。

こんな感じの↓

https://easings.net/ja

さっそくバウンドするようなイージングを使おうと思いました。

ところが、やってみてもうまくいきません。

よくよく見ると、ティラノのkanimには、基本的なイージングしか実装されてないようです。(kanimではなく、animのほうにはもっと種類があるのですが)

指定できる値としてease(開始時点と終了時点を滑らかに再生する) linear(一定の間隔で再生する)ease-in(開始時点をゆっくり再生する)ease-out(終了時点をゆっくり再生する)ease-in-out(開始時点と終了時点をゆっくり再生する)

困った・・。のですが、先を読むと、

 この他に、cubic-bezier関数を使って、イージングを独自に設定することも可能です

 というわけで、こちらのサイトを参考に、バウンドする動きを作ってみました。

cubic-bezier.com

その結果が easing="cubic-bezier(.38,1.37,.99,1.09)" です。

 

あとは、自動的に数字が消えるアニメを実装したいなと思います。

 

・バウンドと同時に透明から現れていく例

[keyframe name="float_ability"]
[frame p=" 0%" opacity=0]
[frame p="100%" y="-100" opacity=255]
[endkeyframe]

・バウンドと同時に透明から現れていく例(失敗例。バウンドと同時にならない)

[keyframe name="float_ability"]
[frame p=" 0%" opacity=0]

[frame p=" 25%" opacity=255]
[frame p="100%" y="-100" ]
[endkeyframe]

 

その他気づいたところ

・「バウンドして表示後に、自動的に消える」を一気にやるには、透明になる動きまで含めたcubic-bezier関数を作る必要があり、若干面倒

 ・kanimはデフォルトでアニメ終了を待たずに次の処理に進むので、アニメしながら本文を読み進めやボタン処理等ができる。

 animはアニメ終了待ちのためのタグ[wa]がある。

 ・[chara_new][chara_show][chara_mod]など、キャラ表示関連のタグは、name属性を一個しか指定できない。

キャラクターを以後操作するための名前を半角英数で指定します。このnameは他のタグを含めて必ずユニークでなければなりません

 つまり、これらのタグを使って表示させた画像は、全部同じ名前にしておかないと同時にアニメ操作できない。

imageやptextなどのタグでは、名前は複数登録できるので、

name="chara1,chara_all"

name="chara2,chara_all"

name="chara3,chara_all"

 などと登録しておいた3つの画像があるとき、"chara1"で一個だけアニメさせたり、"chara_all"で全部同時にアニメできた。

ところが[chara_new]関連のタグを使うと、名前が一個しか登録できないため、上記のような個別アニメと全体アニメの使い分けができないということになる。

 

ティラノスクリプトで文字列の内容を調べる

ティラノで文字列の内容を調べる方法です。

星取表を作っていました。

相撲で勝敗を記録するあれです。文字列変数に勝負の終了ごとに○や●を加えていって、

f.hoshi=f.hoshi+'○'

f.hoshi=f.hoshi+'●'

という感じで試合を繰り返すと、f.hoshiの内容が'○●●○○○'となっていきます。

文字列変数ですから、星取表を表示するにはそのまま変数の内容を表示すればいいのですが、じゃあ何番目の取り組みが○なのか●なのか、みたいに、勝敗の内容を取り出すときには工夫がいります。

 

変数を別に用意する方法

試合ごとに数字の変数を用意して、勝ったら1、負けたら0、を変数に代入していく方法もあります。(for文でいじりやすいように配列変数を使う)

f.shiai[1]=1

;1試合目勝

f.shiai[2]=0

;2試合目負け

f.shiai[3]=0

;3試合目負け

 これだと何試合目が勝ったか負けたかダイレクトに調べることができるのでわかりやすいですが、変数が増えてしまうのが面倒かもしれません。

 

文字列変数の内容を調べる方法

こちらが本題です。f.hoshiに入っている'○●●○○○'という文字列を直接調べます。

tyrano.wiki.fc2.comwikiから引用させていただきました。

[eval exp="f.itemname='うすよごれたコップ'"]
[if exp="f.itemname.indexOf('コップ')!=-1"]
コップなら持ってる。
[endif]

このように、調べたい変数の後ろに .indexOf('調べたい文字列')をつけると、

調べたい変数の「何文字目」に「調べたい文字列」があるかわかるのです。

上記に引用したサンプルでは、-1文字目以外に 'コップ' があれば、「コップなら持ってる。」のメッセージ表示となります。( !=-1で評価しているので、-1以外なら、となります)

つまり、うすよごれたコップでも、きれいなコップでも、「コップ」という文字列の含まれるアイテムを所有していれば「コップなら持ってる。」になります。

 

[eval exp="f.itemname='うすよごれたコップ'"]
[if exp="f.itemname.indexOf('コップ')==6"]
6文字目に「コップ」がある。(文字列の先頭は0なので0から数えて6文字目)
[endif]

 ちょっと改造しました。調べたい変数のN文字目に「調べたい文字列」があるかどうか。の判定です。==6のところを7とか5にすると、何も起きません。6のときだけ、「6文字目に「コップ」がある。(文字列の先頭は0なので0から数えて6文字目)」という表示になります。

 

[eval exp="f.itemname='うすよごれたコップ'"]
[eval exp="f.n=f.itemname.indexOf('コップ')"]
文字列の先頭から[l]
[emb exp="f.n"][l]
文字目にコップがある。(文字列の先頭は0なので0から数えて)

また別な改造です。調べたい変数の「何文字目」に「調べたい文字列」があるか、を調べます。結果は、「文字列の先頭から6文字目にコップがある。(文字列の先頭は0なので0から数えて)」となります。

f.itemname='うすよごれたコップ'を、f.itemname='すごくうすよごれたコップ'にすると、「文字列の先頭から9文字目にコップがある。(文字列の先頭は0なので0から数えて)」となるかと思います。

 

以上の方法を使うと、「f.hoshiに入っている'○●●○○○'という文字列」の何番目が○で何番目が●なのか、を調べることができます。

 

こういった文字列に対する操作は、吉里吉里のサイトも参考にさせていただきました。

文字列に対する操作