9.15 レイヤ移動機能を拡張する(その1)

さて、今回から move タグの拡張をやってくわけだけど、 今回はまず最初に move タグの拡張版を使ってみよっか。
あ、今回はスクリプトの説明する前に使ってみるんだ?
ん、その方がスクリプトの説明がしやすいかなーと思って。
そーなんだ。
りょーかい。
それじゃスクリプトはここに置いとくから、 まず first.ks を見てみて。
は〜い。

<first.ks の中身(一部)>

; exmove マクロ(move タグの拡張版)の定義を読み込みます
[call storage="exmove.ks"]

; eximage マクロの定義を読み込みます
; ※exmove マクロを使う時には eximage.ks を必ず読み込むようにしてください
[call storage="eximage.ks"]

; メッセージレイヤを非表示にします
[position layer=message0 page=fore visible=false]

; 0 番の前景レイヤに読み込む画像名を指定します
[eval exp="tf.storage = 'krkr'"]

*exmove1

(以下略)

ずいぶん長いねぇ…
path 属性の書き方がちょっとややこしくなってたりするから、 その辺の説明を書いてたら長くなっちゃったんだ。
確かにコメントが多いね。
んじゃ実行しつつスクリプトを見ていこっか。
とりあえず実行してみて。画像が拡大したり回転したりするはずだから。
おっけー。

<実行結果>

 (略)

ホントだ、画像が拡大しながら回転してるね〜。
…って実行結果の画像は?
レイヤが動いたりすると実行結果の画像作るのがタイヘンだから、今回は省略ってコトで。
なんか前にもそんなコト言ってなかった?
まぁね。でもこういうのは実際にスクリプトを実行してみるのが一番わかりやすいでしょ。
まーそれはそーだけどね。
それじゃこの部分のスクリプトを見てくね。
はーい。

<画像を拡大・回転・不透明度変更しながら移動させるスクリプト>

*exmove1

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=100 top=100 opacity=255 scale=100 angle=0 visible=true]
; 1秒待ちます(特に意味はありませんが、レイヤの初期位置がどこかわかりやすくするために待っています)
[wait time=1000]
; レイヤを移動・拡大・回転します
[exmove layer=0 page=fore time=2000 path="(250,150,128,150,60)"]
; 移動・拡大・回転の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

まず最初に eximage マクロで画像を読み込んでるんだけど、 これは大丈夫だよね?
eximage マクロについては §9.1 参照。
storage 属性の &tf.storage ってゆーのは?
あー、これはね、first.ks の中で何回か eximage マクロで画像を読み込んでるんだけど、直接ファイル名を指定すると、 他の画像を使いたくなった時にいちいち全部書き換えなきゃいけなくなって面倒だからエンティティを使うことにしたの。
ちなみに tf.storage にファイル名を代入してるのはこの eval タグのとこね。
じゃあ tf.storage = 'krkr' になってるから、 いつもの 吉里吉里のアイコン画像 が読み込まれるってことだよね?
そうそう。他の画像を使いたくなったらこの 'krkr' の部分だけ変えれば eximage マクロの storage 属性は変えなくてもいいよ。
なるほどね。
あと、scale 属性が 100angle 属性が 0 になってるけど、 これって拡大も縮小も回転もしないってコトだよね?
そだよ。拡大率 100%(等倍)で回転角 ってことだからね。
別に書かなくてもいいんだけど、初期値がわかりやすいように書いてるだけだよ。
そっか。
後の属性は image タグにもあるからわかるよね?
うん。
んじゃ次は exmove マクロを見てくね。
え〜っと…指定されてる属性は move タグとおんなじみたいだけど、path 属性の書き方が違ってるよね?
move タグだと (200,150,128) って感じで lefttopopacity の値を指定するけど、exmove マクロの path 属性には値が5つ指定されてるね。
増えた分の2つが何の値かは予想つくでしょ?
scaleangle、かな?
ん、そのとーり。
exmove マクロの path 属性には left, top, opacity, scale, angle の値を (left,top,opacity,scale,angle) っていう形式で指定するようにしてるんだ。
えっと、じゃあこの exmove タグを実行すると、 0 番の前景レイヤが (250,150) の位置に移動して、 不透明度(opacity)128 になって、 あとレイヤが 150% に拡大されて 60°回転するってことだよね?
そういうこと。
ちなみに angle はプラスの値だと時計回りに回転して、 マイナスの値だと反時計回りに回転するよ。
じゃあ path="(250,150,128,150,-60)" にしたらレイヤが反時計回りに 60°回るってこと?
そ。あと一つ注意して欲しいのが、lefttop の指定の仕方。
え? (250,150) の位置に移動するんじゃないの?
確かに (250,150) の位置には移動するんだけど、 レイヤの左上の位置が (250,150) になるんじゃなくって、 拡大とか回転の中心の位置が (250,150) に来るように移動するの。
拡大とか回転の中心の位置って?
レイヤを拡大・縮小したり回転したりしても位置が変わらない点のことだよ。

<レイヤの拡大・縮小・回転の中心点の例>

ちなみに普通は上の図みたいに画像(レイヤ)の中心が拡大とか回転の中心になるんだ。
なるほどね。
でもなんで拡大とか回転の中心の位置を指定するようにしたの?
レイヤの左上の点を指定するようにすると、前回やったみたいに画像を回転させるのが難しくなっちゃうから。
え、そーなの?
だってレイヤの中心点は回転しても位置が変わらないけど、 レイヤの左上の点は回転すると位置が変わっちゃうから座標を指定するのが難しいでしょ。
じゃあレイヤの左上を中心にして回転させればいいんじゃない?
まぁそーなんだけど、どっちかって言うとレイヤの左上を中心にして回すより、 レイヤの真ん中を中心にして回す機会の方が多いんじゃないかな。
あ、確かにそーかも…
ってワケだから拡大とか回転の中心点の位置を指定するようにしたの。
後で説明するけど、ちゃんとレイヤの左上の点を中心にして回転させられるようにもしてるよ。
あ、そーなんだ。
じゃ最後にこの exmove マクロを実行する前と後のレイヤの状態を図にしてみるね。

exmove マクロを実行する前(上の図)と後(下の図)のレイヤの状態>

上の方が exmove マクロを実行する前のレイヤの状態で、 下の方が実行した後のレイヤの状態ね。
あと、ここに書いてる通り、exmove マクロを実行した後レイヤの移動を待つ時は wm タグを使ってね。
move タグを使う時とおんなじだね。
ん。それと stopmove タグでレイヤの移動を止められるよ。
それも move タグの時とおんなじだね。
じゃ今度は別の exmove マクロを実行してみよっか。
さっきの exmove マクロを実行し終わった後で画面をクリックしてみて。
りょ〜かい。
実行中…
今度はなんかフツーに移動したね。
拡大も縮小も回転もしてないからね。
あ、そーなんだ。
じゃスクリプト見てくね。

<レイヤの移動と不透明度変更のみ行うスクリプト>

*exmove2

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=100 top=200 opacity=128 scale=100 angle=0 visible=true]
; 1秒待ちます
[wait time=1000]
; レイヤの移動・不透明度変更のみ行います
[exmove layer=0 page=fore time=1000 path="(200,300,192)(300,200,255)"]
; 移動の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

最初に exmove マクロを実行した時のスクリプトとほとんどおんなじだから、exmove マクロの path 属性だけ見てくね。
あれ? さっきは5つ値を指定してたのに、今度は3つしかないよ?
レイヤを拡大・縮小したり回転したりする必要がない時は scaleangle の値は省略できるようにしたんだ。
だから、こんなふうに move タグと全く同じ書き方もできるの。
へぇ、そーなんだ。
じゃあこれって…

[move layer=0 page=fore time=1000 path="(200,300,192)(300,200,255)"]

この move タグを実行するのとおんなじってコト?
ん、同じだよ。
あと拡大・縮小はするけど回転はしないって時には…

[exmove layer=0 page=fore time=1000 path="(200,300,192,150)(300,200,255,200)"]

こんなふうに書けるよ。
scale は指定してるけど angle は省略してるから4つになってるんだね。
そういうこと。
それから、今度は逆に拡大・縮小とか回転はするけど移動したり不透明度を変えたりはしないって時には…

<レイヤの拡大・回転のみ行うスクリプト>

*exmove3

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=100 top=100 opacity=255 scale=100 angle=0 visible=true]
; 1秒待ちます
[wait time=1000]
; レイヤの拡大・回転のみ行います(200%に拡大・反時計回りに45°回転します)
[exmove layer=0 page=fore time=1500 path="(,,,200,-45)"]
; 拡大・回転の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

こんな感じで、lefttopopacity の値を省略できるよ。
なんかヘンな書き方だね…
(left,top,opacity,scale,angle) の中の left, top, opacity を省略すると (,,,scale,angle) になるでしょ?
あ、そっか。確かにそーなるね。
んじゃ次のスクリプトいくね。
まだあるんだ?
ん、path 属性には色々書けるようにしたからねー。

path 属性の相対値指定(その1)>

*exmove4

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=100 top=200 opacity=128 scale=100 angle=0 visible=true]
; 1秒待ちます
[wait time=1000]
; レイヤの拡大・回転のみ行います(200%に拡大・反時計回りに45°回転します)
[exmove layer=0 page=fore time=1000 path="(@+100,@+100,@+64)(@+200,@,@+127)"]
; 拡大・回転の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

なんか @+100 とか書いてあるけど…何コレ?
@ は初期値を表してるんだ。
初期値?
例えば、left 属性を 100 にして eximage マクロを実行してるから、 left の初期値、つまり exmove マクロを実行する前の left100 になってるわけね。
ん? でもさっき lefttop はレイヤの左上じゃなくて拡大とか回転の中心の位置になるって言ってたよね?
この 100 ってレイヤの左上の位置なんじゃないの?
あー、えっとね、画像を拡大・縮小したり回転したりする場合は lefttop は拡大・縮小・回転の中心の位置になるんだけど、 拡大も縮小も回転もしない時は lefttop はレイヤの左上の位置になるんだ。
え、そーなの? でもそれってなんか紛らわしくない?
ん〜…確かにそうは思ったんだけどね。
拡大とか回転する場合はさっきも言ったようにレイヤの左上の位置を指定するのは難しいから、 中心点の位置を指定するようにした方が使いやすいと思うんだけど、 拡大も縮小も回転もしなかったら中心点なんてないわけだから、中心点の位置って指定しようがないんだよね…
だからこうするしか思いつかなかったんだ。
そーなんだ…
とりあえず scaleangle を指定する時は lefttop には中心点の位置を指定して、 scaleangle も指定しない時は lefttop にはレイヤの左上の位置を指定するって覚えといてもらえるかな?
うん、わかった。
それじゃ @ の話に戻るね。
left の場合だと初期値が 100 だから、 @+100100+100200 になるんだ。
あと top の初期値は 200 だから、 @+100100+200300 になるの。
えっと、じゃあ opacity は初期値が 128 だから、@+64128+64192 になるってコト?
そうそう。
つまり (@+100,@+100,@+64)(200,300,192) とおんなじ意味になるってことだね。
(@+200,@,@+127) の方は (100+200,200,128+127) になるから (300,200,255) と同じ意味になるの。
ってことは、結局 path="(@+100,@+100,@+64)(@+200,@,@+127)"path="(200,300,192)(300,200,255)" とおんなじなの?
ん、そうだよ。
だからこのスクリプトを実行してもこっちのスクリプトを実行してもレイヤの動きは同じになるワケ。
あ、ホントだ。どっちも path 属性が同じになるんだね。
…でもなんでわざわざこんな書き方が出来るようにしたの?
例えば、eximage で画像を読み込む時に、レイヤの位置をこんなふうに変えたとするね。

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=200 top=100 opacity=128 scale=100 angle=0 visible=true]

ん〜と…さっきleft100top200 だったから…
left200 にして top100 にしたってこと?
そ。で、レイヤの初期位置はこんなふうに変えるけど、 レイヤの動かし方(最初に右下に動いてその後右上に動くっていう動き方のことね)は変えたくないっていう場合には、 path 属性を "(300,200,192)(400,100,255)" にしなくちゃいけないよね。

<レイヤの動かし方は変えずに初期位置だけを変える例>

うん、確かにそーみたいだね。
こういう時に、こっちのスクリプトみたいに path 属性の中身を全部数字で指定してると、 path 属性を全部書き変えなくちゃいけなくなるんだけど、 path="(@+100,@+100,@+64)(@+200,@,@+127)" って書いとくと全然書き変えなくてもよくなるんだ。
えっ、そうなの?
実際計算してみればわかると思うよ。
まず left は初期値が 200 になったから、 @+100200+100300 になるし、@+200200+200400 になるよね。
あと topopacity も計算してみて。
えっと、top は初期値が 100 になったから、 @+100100+100200 になって、@ はそのまま 100 だよね。
それから、opacity は初期値が変わってないから、 @+64@+127 はそれぞれ 192255 だね。
じゃ結局 path 属性はどうなるかな?
left300→400 で、 top200→100 で、 opacity192→255 だから…
path="(300,200,192)(400,100,255)" だね。
ほらね、path 属性の中身を書き変えなくてもちゃんと設定できてるでしょ?
あ、ホントだ。
こんなふうにちょっとスクリプトを書きやすくするために @ で初期値を指定できるようにしたんだ。
なるほど、確かにちょっと便利になった感じだね。
あともう一つこんな書き方もできるようにしてるよ。

path 属性の相対値指定(その2)>

*exmove5

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=100 top=200 opacity=128 scale=100 angle=0 visible=true]
; 1秒待ちます
[wait time=1000]
; レイヤの拡大・回転のみ行います(200%に拡大・反時計回りに45°回転します)
[exmove layer=0 page=fore time=1000 path="($+100,$+100,$+64)($+100,$-100,$+63)"]
; 拡大・回転の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

今度は $+100 とか書いてある…
$ は1つ前の区間の値を表すんだ。
1つ前の区間って?
例えば、path="(200,300,192)(300,200,255)" だと (200,300,192) が最初の区間で (300,200,255) が2番目の区間だよ。
えっと、じゃあ path="($+100,$+100,$+64)($+100,$-100,$+63)" だとどーなるの?
最初の区間の1つ前の区間は初期値ってことにしてるから、 ($+100,$+100,$+64) の部分は (100+100,200+100,128+64) になるね。
つまり (200,300,192) ってコト?
そ。で、2つ目の区間 ($+100,$-100,$+63) の1つ前の区間は最初の区間 (200,300,192) だから、 2つ目の区間は (200+100,300-100,192+63) になるの。
つまり (300,200,255) だよね?
だから結局 path="($+100,$+100,$+64)($+100,$-100,$+63)"path="(200,300,192)(300,200,255)" になるわけだね。
それってさっきやった path="(@+100,@+100,@+64)(@+200,@,@+127)" とおんなじじゃない?
ん、だからこういう書き方もできるってこと。
だったら別に @ だけでいいよーな気がするんだけど…?
path 属性の中身によって @ の方が使いやすい場合と $ の方が使いやすい場合があると思うから、 どっちも使えるようにしたの。
まぁ必要なければこの書き方は使わなくてもいいわけだしね。
ふぅん…そっか。
んじゃ次いくね。
ま、まだあるの?
path 属性の書き方についてはこれが最後だよ。

<変数を使った path 属性の指定>

*exmove6

; 以下の値(global.r)を変えるとレイヤの動きが変わります
[eval exp="global.r = 200"]
; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage opacity=255 scale=100 angle=0 visible=true]
; 1秒待ちます
[wait time=1000]
; レイヤの位置を調整します
[layopt layer=0 page=fore left="&(kag.scWidth - kag.fore.layers[0].width) \ 2 - r" top="&(kag.scHeight - kag.fore.layers[0].height) \ 2"]
; レイヤを半径 r の円周上に沿って移動します
[exmove layer=0 page=fore time=250 spline=true path="(@+0.3*r,@-0.7*r)(@+r,@-r)(@+1.7*r,@-0.7*r)(@+2*r,@)(@+1.7*r,@+0.7*r)(@+r,@+r)(@+0.3*r,@+0.7*r)(@,@)"]
; 拡大・回転の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

なんか今度のはすごいフクザツそーなんだけど…
細かい計算とかは気にしなくて大丈夫だから、path 属性だけ見てみて。
(@+0.3*r,@-0.7*r) とか書いてあるね。
@ はさっき出てきたけど、 r は初めて出てくるよね。
その rここの eval タグに書いてる global.r っていう変数のことだよ。
えっと、それってつまり path 属性の中に変数を書いてもいいってこと?
うん、そういうこと。
ちなみにここではグローバル変数を使ってるけど、 システム変数とかゲーム変数とか一時変数とかももちろん使えるよ。
あ、そーなんだ。
う〜ん、でも普通は path 属性を書く時にわざわざ変数を使う必要ないよーな気はするけどねぇ…
まぁシンプルな移動とかの場合は確かに必要ないかもね。
じゃちょっとこの *exmove6 っていうラベルのとこ実行してみて。
りょーかい。ちょっと待ってね…
実行中…
なんかレイヤがぐるっと回ったね。
その言い方だとレイヤ自体が回転したみたいだよね。
あ、えっと、そーじゃなくって、何て言ったらいいのかな…
レイヤ自体は回転してないんだけど、レイヤの位置が回った…っていうのもヘンだよね…
んー…こんなふうにレイヤが円周上を移動したって感じかな?
※スプライン補間を使用しているので厳密には円周上を移動するわけではありませんが、円運動を近似した動きになっています。

<レイヤの移動の軌跡>

あ、そーそー、こんな感じだよね。
…ってゆーか最初からこの画像出してくれればよかったのに〜。
あはは、ゴメンね。
ま、それはそうとして、この図に「r=200ピクセル」って書いてあるでしょ。
うん、書いてあるね。
これってレイヤが通ってる円の半径になってるのかな?
そうそう。
で、この rこの eval タグglobal.r を表してるんだ。
だから、global.r に代入する値を変えると、レイヤの動き方が変わるの。
へぇ、そーなんだ。
試しに global.r の値を変えて実行してみて。
おっけー。
global.r = 100 とかでいいかな?
ん、それでいいよ。
じゃあ実行するね。
実行中…
100 にしたらレイヤの動きが小さくなったね。
レイヤが移動する円の半径が半分になったわけだからね。
こんなふうに path 属性に変数を入れとくと、 変数の値を変えるだけで色んな動かし方が試せるってワケ。
なるほどねぇ。
でもこれってかなりムズカシイ使い方じゃない?
まぁこの例の場合はちょっとややこしいかもね。
でもその辺は使い方次第かな。
ふぅん、そーなんだ。
それじゃ最後に cx 属性と cy 属性の使い方を見てくね。
cx 属性と cy 属性?
…って move タグにはないよね?
ん、この2つの属性は exmove マクロ専用の属性だよ。
どんな属性なの?
cx 属性と cy 属性はそれぞれ x 方向と y 方向の拡大・縮小・回転の中心点を指定する属性だよ。
拡大・縮小・回転の中心点ってさっき言ってたののことだよね?
ん、こんな感じで cx 属性と cy 属性を指定すると、中心点の位置が設定できるんだ。

<画像の拡大・縮小・回転の中心点を指定するスクリプト>

*exmove8

; 画像を読み込みます
[eximage layer=0 page=fore storage=&tf.storage left=100 top=100 opacity=255 scale=100 angle=0 visible=true]
; 1秒待ちます
[wait time=1000]
; (16,48) の点を中心としてレイヤを拡大・回転します
[exmove layer=0 page=fore time=1200 cx=16 cy=48 path="(,,,150,60)"]
; 拡大・回転の終了を待ちます
[wm]
; クリック待ちします
[waitclick]
※説明用にコメントを改変しています。

このスクリプトの場合は cx=16, cy=48 だから、 こんなふうに (16,48) の位置を中心として拡大・回転するの。

(16,48) の位置を中心とした拡大・回転>

ちなみに cx=0, cy=0 にすると、左上の点を中心にして拡大・縮小・回転するよ。
あ、そーいえばさっき左上を中心点にすることもできるって言ってたね。
あと cx, cy 属性はこうやってパーセント単位でも指定できるよ。

<パーセント単位での cx, cy属性の指定>

[exmove layer=0 page=fore time=1200 cx=25% cy=75% path="(,,,150,60)"]

cx=25% cy=75% って書いてあるけど、これどーいう意味なの?
eximage マクロで読み込んだ画像の幅と高さがそれぞれ 64 ピクセルだとすると、 cx 属性は 64(画像の幅)の 25% になるから、 64×0.2516 になるんだ。
cy 属性の方は 64(画像の高さ)の 75% になるから、 64×0.7548 になるの。
じゃあ結局さっきのスクリプトexmove マクロとおんなじってコト?
ん、そう。ちなみにパーセント単位で指定できるようにしたのは、 画像の幅とか高さに無関係に中心点を決められるようにするためだよ。
え、どーゆーコト?
例えば、cx=50% cy=50% って指定すると、 画像の幅や高さが何ピクセルだったとしても、画像の真ん中の位置を表すことになるから、 どんな画像がレイヤに読み込まれてても画像の真ん中が拡大・縮小・回転の中心点になるんだ。
へぇ、なるほどねぇ。
cx 属性と cy 属性はどっちもデフォルトを 50% にしてるから、省略すると画像の真ん中が拡大・縮小・回転の中心点になるよ。
そっか。だから今まで画像の真ん中が中心点になってたんだね。
んじゃこれで exmove マクロの使い方は一通りチェックできたから、 今回はこの辺にしとこっか。
そーだね。
あ、そうそう。exmove マクロを使う時には注意してもらわないといけない事がいくつかあるんだ。
え、何に注意しなくちゃいけないの?
まず、ここに書いてる通り、exmove マクロを使う時には exmove.ks と一緒に eximage.ks も読み込むようにしてね。
eximage.ks って eximage マクロの定義が書いてあるファイルのことだよね?
そだよ。exmove マクロは eximage.ks の中で定義されてるメソッドを使ってるから、 eximage.ks が読み込まれてないとちゃんと動かないんだ。
それに exmove マクロで画像(レイヤ)を拡大・縮小・回転した後にセーブしたら、 セーブデータを読み込むときに拡大・縮小・回転後の画像を復元しなくちゃいけないわけだけど、 eximage マクロが定義されてないとそれもできなくなっちゃうからね。
あ、そー言えば eximage マクロ作った時に画像の復元とかやったよね。
§9.11§9.12 参照。
それともう一つ、exmove マクロは前景レイヤにしか使えないから注意してね。
確か eximage マクロも前景レイヤにしか使えなかったよね?
ん、その関係で exmove マクロも前景レイヤにしか使えなくなってるんだ。
そっか、わかった。
それじゃ次回から exmove マクロのスクリプトを見てくことにするね。
…ねぇ、さっきちょっと exmove.ks の中身を見てみたら、 すごい長いし難しそうだったんだけど…
んー、できるだけシンプルにするつもりだったんだけど、 色々機能をつけてくうちに複雑になっちゃったんだよね。
さすがにコレ理解するのはムリそうだよ…
そう思って exmove.ks をもっとシンプルにしたスクリプトも作っといたから、 次回からはそっちの方を見ていくつもりだよ。
それってカンタンなの?
exmove.ks のスクリプトよりはね。
でも今まで作ってきたスクリプトの中では一番難しいかも。
だよねぇ…やっぱり。
まぁとりあえず見てくだけ見ていこ。
は〜い。
それじゃ、また次回ね。


前へ | TOP | 次へ