11.2 データをタウンロードする(その2)

今回も download マクロを使ってデータをダウンロードしてみるね。
前回ダウンロードしたのってテキストだけだったけど、他のファイルもダウンロードできるんだよね?
うん。
じゃあまずは画像ファイルをダウンロードしてレイヤに表示してみよっか。
は〜い!
あ、その前に、テキスト以外をダウンロードして使う時は、もう一つプラグインが必要なんだ。
httprequest.dll の他にもプラグインがいるってこと?
そう。
で、そのプラグインも httprequest.dll と同じように、吉里吉里開発サイトで公開されてるから、 ここからダウンロードして使わせてもらうことになるね。
そーなんだ。
それってどんなプラグインなの?
varfile.dll っていうプラグインで、httprequest.dll の時と同じように、 プラグインが色々公開されてるページvarfile.dll のリンクからダウンロードできるよ。
ちなみに ReadMe ファイルも httprequest.dll の時と同じように、 プラグイン関係の文書やソースコードが公開されてるページ varfile.dll のリンクからダウンロードできるから確認しといてね。
うん。わかった。
で、varfile.dll なんだけど、ReadMe には「吉里吉里の変数空間を直接参照するファイルシステムを構築するプラグインです」って書いてあるね。
? それってどういうこと?
ん〜、そーだね…
例えば、画像をレイヤに表示する時は、普通はプロジェクトフォルダに置いてある画像ファイルのファイル名を指定して画像を読み込むよね。
そーだね。
つまり、普通にレイヤに画像を表示する時は、こんなふうにハードディスクに入ってる画像ファイルから直接画像データを取ってきて、レイヤに表示してるわけだね。

<普通に画像をレイヤに表示する場合>

で、varfile.dll を使うと、変数にファイルの中身を入れて、その変数を使って画像を読み込めるようになるんだ。
つまり、こんな感じだね。

<ダウンロードした画像をレイヤに表示する場合>

まず、httprequest.dll を使って画像データをダウンロードして、それを変数に入れとくと、varfile.dll がその変数を使ってレイヤに画像を読み込めるようにしてくれるの。
変数って数字とか文字とかだけじゃなくて、ファイルの中身も入れられるんだ?
うん。普通は変数には数値とか文字列とかオブジェクトを入れて使うんだけど、 ファイルの中身も入れられるようになってるんだ。
※varfile.dll はオクテット型(主にバイナリデータを扱うための型)の変数をストレージ(ファイル)として扱うことができます。
へぇ、そーなんだ。
この方法を使えば、ダウンロードしてきたデータをハードディスクに一旦保存しなくても使えるんだ。
なるほどね。
それじゃ、実際に画像をダウンロードしてレイヤに表示してみよっか。
うん!
んー…ダウンロードする画像は……
まぁさっき説明に使った図でいっか。
えっ…なんかテキトーだね…
ま、まぁとりあえず実際やってみよってだけだから、画像にはこだわらないってことで、ね。
まーいいけどね。
じゃ、httprequest.dll と varfile.dll と HttpRequestEx.ks をプロジェクトフォルダに置いてから、このスクリプトを実行してみて。

downloadマクロを使って画像をダウンロードしてレイヤに表示するスクリプト>

; HttpRequestEx.ks を読み込みます
[call storage="HttpRequestEx.ks"]

; http://tjs2.info/img/TJS110201.png をダウンロードして、画像のストレージ名を tf.image に代入します
[download url="http://tjs2.info/img/TJS110201.png" storage=tf.image]
[if exp="tf.image !== void"]
; ダウンロードが成功すると、tf.image にストレージ名が代入されますので、
; image タグで表ページの 0 番の前景レイヤに読み込みます。
; ストレージ名は変数(tf.image)に代入されていますので、
; image タグの storage 属性にはエンティティを使用する必要があることに注意してください。
[image storage=&tf.image layer=0 page=fore]
; レイヤを見える状態にします
[layopt layer=0 page=fore visible=true]
[else]
; ダウンロードに失敗すると tf.image が void になるので、その場合はエラーメッセージを表示します
[eval exp="System.inform('データをダウンロードできませんでした。')"]
[endif]

じゃあ実行してみるね。

<実行結果>

あっ!画像が表示された!
ちゃんとさっき説明に使った画像が表示されたでしょ。
されたね〜!
ちなみに、実行する環境によっては表示するのに時間がかかるかもしれないから、実行した後しばらく待ってみてね。
それって画像をダウンロードするのに時間がかかるかもしれないってことだよね?
そう。画像データはテキストデータに比べてデータサイズが大きくなることが多いからね。
そっか。
それじゃ、スクリプトの方を見てこっか。
…って言っても、前回テキストデータをダウンロードした時とあんまり変わらないけどね。
最初の HttpRequestEx.ks を読み込むとこは前回と同じだよね。
download マクロは…url 属性が指定されてるのは前回と同じだけど、 今回は text 属性じゃなくって、storage っていう属性が指定されてるね。
今回ダウンロードするのはテキストデータじゃなくて画像データだからね。
まぁそうだよね。
それで、この storage 属性ってどういう属性なの?
image タグでレイヤに画像を読み込もうと思ったら、 image タグの storage 属性に画像のファイル名を指定する必要があるでしょ。
うん、あるね。
だけど、ダウンロードしてきたデータは、さっきも言ったようにファイルじゃなくて変数に入れられるから…
そっか、じゃあ storage 属性に指定した変数に、 ダウンロードしてきたデータが入れられるんだね。
ううん、そうじゃないよ。
えっ、違うの?
だって image タグの storage 属性には画像のファイル名を指定するでしょ。
うん。
だから、ダウンロードしてきたデータが入ってる変数を image タグの storage 属性に指定しても、画像は読み込めないよね。
あ、そう言われればそーだね。
じゃあ download マクロの storage 属性って一体何なの?
download マクロの storage 属性に指定した変数(この例の場合だと tf.image ね)には、 ダウンロードしてきたデータの名前が代入されるの。
ダウンロードしてきたデータの名前…?
まぁファイル名みたいなものって思ってOKだよ。
だから、この名前を image タグの storage 属性に指定すると、ちゃんと画像をレイヤに読み込んでくれるんだ。
※実際には、“var://./httpRequestExVars/0.png”のように、メディアが“var”、ドメインが“.”(ドット)の統一ストレージ名を storage 属性に指定した変数に代入し、ダウンロードしたデータをストレージとして扱えるようにしています。なお、ドメインより後の名前は HttpRequestEx クラス(HttpRequestEx.ks 内で定義)でダウンロードしたデータごとに割り当てています。また、ダウンロードしてきたデータは、グローバルオブジェクトに含まれる辞書配列(前述のストレージ名の場合は global.httpRequestExVars["0.png"] )に保存されます。
ふぅん、そーなんだ。
後のスクリプトは前回のテキストをダウンロードするスクリプトとそんなに変わらないし、 image タグとか layopt タグは大丈夫だよね?
うん。
…あ、画像をダウンロードする時も、ダウンロードに失敗したら storage 属性に指定した変数に void が代入されるの?
そうだよ。
だから storage 属性に指定した変数が void かどうかを調べれば、 ダウンロードが失敗したか成功したかがわかるよ。
りょーかい。
レイヤに表示してる画像って、要らなくなったら freeimage タグで解放できるよね。
え? あ、うん、そーだね。
download マクロでダウンロードしたデータも、これと同じように、 要らなくなったら解放できるんだ。
そーなの?
うん。
まぁ解放しなくても特に KAG の動作には影響ないんだけど、 画像みたいに結構サイズが大きいデータは、ダウンロードしたまま放っとくとメモリを無駄に使っちゃうから、 できるだけ要らなくなったら解放した方がいいと思うよ。
えっと、じゃあ download マクロでダウンロードした画像が要らなくなったら、 freeimage タグを実行すればいいってこと?
残念ながら、download マクロでダウンロードしたデータは freeimage タグじゃ解放できないんだ。
え、じゃあどーするの?
download マクロでダウンロードしたデータを解放するための freedownload っていうマクロを実行するの。
freedownload マクロ…?
そ。例えばこんな感じだね。

freedownloadマクロを使ってダウンロードしたデータを解放するスクリプト>

; HttpRequestEx.ks を読み込みます
[call storage="HttpRequestEx.ks"]

; http://tjs2.info/img/TJS110201.png をダウンロードして、画像のストレージ名を tf.image に代入します
[download url="http://tjs2.info/img/TJS110201.png" storage=tf.image]
[if exp="tf.image !== void"]
; …
; 何かの処理
; …
; これ以後ダウンロードした画像を使う必要がなくなったとします
; まず freeimage タグでレイヤの画像を解放します
[freeimage layer=0 page=fore]
; freeimage タグとは別に freedownload マクロを実行して画像データを解放します
[freedownload storage=tf.image]
; (これ以降 tf.image を使って画像を読み込むことはできません)
[else]
[eval exp="System.inform('データをダウンロードできませんでした。')"]
[endif]

このスクリプトは、さっきのスクリプトと同じ、画像をダウンロードするスクリプトなんだけど、 画像が要らなくなった後で画像データを解放してる所がさっきのスクリプトと違ってるよ。
注目して欲しいのは、ダウンロードした画像が要らなくなった後のスクリプトね。
えっと…まず freeimage タグが実行されてて、 その後 freedownload マクロが実行されてるね。
freeimage タグは問題ないよね。
で、freedownload マクロには storage 属性があって、 ここに download マクロの storage 属性に指定したのと同じ変数を指定するの。
この例だと tf.image だね。
つまり、freedownload マクロの storage 属性に指定したデータを解放するってことだよね?
そういうことだね。
freeimage タグでレイヤの画像が解放されるから、 freedownload マクロは必要ないような気がするんだけど、 これって両方実行しなくちゃいけないの?
うん。download マクロを実行してダウンロードした画像をレイヤに表示すると、 ダウンロードして変数に入れられた画像データがコピーされてレイヤに表示されるんだ。
つまり、同じ画像データが2つ出来るわけね。
そーなんだ。でもそれってちょっと無駄な気がするよね。
まぁそうなんだけど、普通ファイルから画像データをコピーしてレイヤに表示するところを、 変数から画像データをコピーしてレイヤに表示するわけだから、これはしょうがないね。
どっちにしても画像データをコピーしなきゃいけないってこと?
ん。だってレイヤの画像が書き換わると、元々その画像が保存されてたファイルの中身まで書き換わっちゃったら大変でしょ。
だからレイヤに画像を表示する時には、画像データのコピーを取ってレイヤに表示するようになってるの。
あ、なるほど。
っていう訳だから、ダウンロードした画像が要らなくなったら、freeimage タグと freedownload マクロを両方実行してね。
はーい。
ちなみに、freeimage タグを実行する代わりに、 image タグで別の画像を読み込んでもOKだよ。
ただ、その場合でも freedownload マクロは実行してね。
うん、りょ〜かい。
それから、download マクロに storage 属性を指定してデータをダウンロードする方法だと、 画像ファイル以外もダウンロードできるから、こんなふうにSEやBGMを再生することもできるよ。

downloadマクロを使ってWave形式のSEをダウンロードして再生するスクリプト>

; HttpRequestEx.ks を読み込みます
[call storage="HttpRequestEx.ks"]

; http://tjs2.info/se.wav をダウンロードして、ストレージ名を tf.se に代入します
; (注意)このファイルは存在しませんので、実際に試される際には適宜 URL を書き換えて実行してください。
[download url="http://tjs2.info/se.wav" storage=tf.se]
[if exp="tf.se !== void"]
; ダウンロードが成功すると、tf.se にストレージ名が代入されますので、
; playse タグで再生することができます。
[playse storage=&tf.se]
[ws]
; ダウンロードしたデータが不要になったら freedownload マクロで解放します
[freedownload storage=tf.se]
[endif]

downloadマクロを使ってOgg Vorbis形式のBGMをダウンロードして再生するスクリプト>

; HttpRequestEx.ks を読み込みます
[call storage="HttpRequestEx.ks"]

; http://tjs2.info/bgm.ogg をダウンロードして、ストレージ名を tf.bgm に代入します
; (注意)このファイルは存在しませんので、実際に試される際には適宜 URL を書き換えて実行してください。
[download url="http://tjs2.info/bgm.ogg" storage=tf.bgm]
[if exp="tf.bgm !== void"]
; ダウンロードが成功すると、tf.bgm にストレージ名が代入されますので、
; playbgm タグで再生することができます。
[playbgm storage=&tf.bgm loop=false]
[wl]
; ダウンロードしたデータが不要になったら freedownload マクロで解放します
[freedownload storage=tf.bgm]
[endif]

へぇ、色んなデータをダウンロードして使えるんだねぇ。
このダウンロードのやり方だと、ダウンロードできるファイルに特に制限はないからね。
ちなみに、画像以外のファイルでも、download マクロに storage 属性を指定してダウンロードしたデータは、 要らなくなったら freedownload マクロで解放してね。
そーなんだ。わかった。
けど、BGMのファイルとかって、ダウンロードするのに結構時間がかかりそうだよね?
んー、確かにサイズが大きいデータは、環境によっては時間がかかるだろうね。
ただ、今どれくらいダウンロードできてるかを表示する機能をつけといたから、 データサイズが大きい時は、表示しとくといいんじゃないかな。
※この機能の実装には HttpRequest クラスの onProgress メソッド(イベント)を利用しています。
え、それってどんな表示なの?
えっとね、こんなふうに download タグに message 属性と page 属性を指定すると、今何%データをダウンロードできてるかが表示されるようになるんだ。

<ダウンロードの進捗状況を表示する場合の download マクロの使用例>

[download url="http://tjs2.info/bgm.ogg" storage=tf.bgm message=0 page=fore]

message 属性がメッセージレイヤの番号で、page は表画面か裏画面かを指定する属性だよ。
だから、この例の場合は、表画面の0番のメッセージレイヤに今どれくらいダウンロードできてるかを表示するわけね。
で、これを実行すると…

<ダウンロード進捗状況の表示例>

※0番のメッセージレイヤは画面の左上に可視状態で配置しています。

こんな感じで、最初は“0%”から始まって、ダウンロードが完了すると“100%”って表示されるの。
確かにこれだと今どれくらいダウンロードが進んでるかがわかるね。
ん。だから必要に応じて使うといいんじゃないかな。
わかった。
download マクロの基本的な使い方は大体こんなとこなんだけど、 いくつか注意してもらわないといけないことがあるから、気を付けてね。
え、注意しなきゃいけないことってどんなことなの?
まず、データのダウンロードは当然インターネットに接続されてる環境じゃないとできないから、 「このファイルがないとスクリプトが正しく実行できない」っていう重要なファイル(例えばタイトル画面の背景画像とかね)は download マクロでダウンロードしないでね。
そっか。download マクロが使えるのは、 ダウンロードできなくても問題ないファイルだけってことなんだね。
そういうこと。
無いと困るファイルは最初から用意しといてね。
配布後に必要になった場合はパッチで配布するとかにしてね。
はーい。
あともう一つ、download マクロでダウンロードしたデータの情報はセーブデータには全然記録されないから、 download マクロの text 属性や storage 属性には、 一時変数(tf)を指定するようにしてね。
ダウンロードした画像とかのデータは、セーブデータを読み込んでもロードされないから、 ゲーム変数(f)とかシステム変数(sf)を指定しないようにしてね。
そーなんだ。わかった。
それから、吉里吉里を終了したらダウンロードしたデータは全部消えちゃうから、 たとえ text 属性や storage 属性に一時変数を指定してても、 ダウンロードした画像が表示されてる状態や、ダウンロードしたサウンドが再生されてる状態でセーブしないようにしてね。
一旦吉里吉里を終了した後にそのセーブデータを読み込んでも、ダウンロードした画像やサウンドのデータが消えちゃってるから元に戻せないってこと?
そういうこと。
だから download マクロでダウンロードして使えるデータは、 「無くても問題ないデータ」で、さらに「セーブする必要の無いデータ」ってことだね。
そっか…でもそれだとあんまり使い道ないんじゃない?
ん〜、確かに制限は厳しいけど、使い方はあると思うよ。
例えば?
そーだね…例えばアップデート(修正)パッチをウェブサイトで配布する場合に、 アップデートがあるかどうかを自動的にチェックしてくれる機能は download マクロで作れると思うよ。
そうなの?
うん。アップデートパッチの自動チェック機能があれば、 アップデートがあることに早く気付いてもらえて良いんじゃないかな。
ん〜、まぁ確かにそーかもね。
ってワケだから、次回は download マクロの実用編ってことで、 アップデートパッチがあるかどうかを自動的にチェックする機能を実際に作ってみるね。
あ、実際に作ってみるんだ?
うん。
それじゃ、また次回ね!


前へ | TOP | 次へ