したらばTOP ■掲示板に戻る■ 全部 1-100 最新50 | |
レス数が1スレッドの最大レス数(1000件)を超えています。残念ながら投稿することができません。

おちゃめくらぶ掲示板

2378御茶目菜子:2015/03/24(火) 00:00:29
プチコン3号のDEFで作った自作関数、命令の解説(上記の続き)
上記の続き

次にフェードイン、フェードアウト命令の解説をするにょ。
フェードイン、フェードアウトに関してはプチコンmkIIでも作ったにょ。

 フェードイン/フェードアウト
 http://ochameclub.web.fc2.com/petitcom/tips/routine.htm#fadein

このプログラムの原理を簡単に説明するとプチコンmkIIではBG(コンソール共用)、GRP、
スプライトは256色のパレット方式(BG、スプライトは16色x16パレット)であるためその
パレットの色を変化させて段階的に黒に近づければフェードアウト、その逆を行えば
フェードインになるにょ。
しかし、256色パレットを3つ分リアルタイムで書き換えるのはプチコンmkIIであっても
かなり重い処理だったにょ。
そのパレットではなくRGB指定のみになったプチコン3号ではピクセル単位で処理をする
必要があり、さらに重くなってしまうかというとそうではないにょ。
実はSPANIMを使えば超簡単に実現できてしまうにょ。

その前に知っておく必要があるのはスプライトではSPCOLORを使って論理色コードをRGB関数
で指定する際にはA(アルファチャンネル)の値で半透明表示が可能ということにょ。
つまり、画面全体を覆うスプライトを用意しておいて黒から透明に変化させていけば
フェードインの完成ということにょ。
黒だけしか使わないならば適当にSPDEFで400x240ピクセルのスプライトを定義すればいいの
だけど黒以外の色も使いたいならばスプライトのベース色は白がいいにょ。
ならば、GFILLを使ってGRP4の400x240の範囲を白く塗りつぶせばいいかというとそんなことを
する必要はなくデフォルトスプライトの中に8x8のサイズの白い四角があるためそれを
SPSCALEで拡大すればいいだけにょ。

8x8ドットならば画面全体を覆うためには50x30倍すればいいかというとそうではないにょ。
立体視の視差による影響や優先順位を考える必要があるためにょ。
画面全体を覆うためにはスプライトのZ座標は-256にする必要があるにょ。
そのようにしたら覆っているスプライトはすごく飛び出て見えそうだけど均一色であるため
左右視差が発生しないので見え方は全く問題はないにょ。(飛び出て見えるというのは
左右で異なる映像が見えているせい)
では、全く問題がないかというとそうではなく400x240の大きなスプライトが左右異なる
場所に表示されているため左端や右端が欠けて見えてしまうにょ。

つまり、左右視差の分だけ左右のサイズは大きくする必要があるにょ。
プチコン3号では最大視差は8ドットなので左右8ドット分大きくすればこの問題は解決
できるけどかなり余裕を持たせて16ドット分としているにょ。(負担増はほとんどない
のでこうすることのデメリットはない)
これはSPSCALEの拡大率は横方向に54倍になり、SPOFSの表示座標はX座標を-16にすると
いうことにょ。

これで特定の色で画面全体を覆うことはできるのであとはそれを段階的に色を変化させる
だけにょ。
それにはSPANIMの"C"オプションを使うと超簡単にょ。
何せ中間色は自分で計算する必要はなく自動的に線形補間してくれるからね。
しかも、何フレームで色を変えるのかも指定できるのでFADEOUT 180とするだけで180
フレーム(3秒)でフェードアウトが可能になるにょ。

ここで注意すべきはフェードインは黒から透明だけを行えばいいのだけどフェードアウトに
関しては透明から黒とは限らないということにょ。
今回作ったSETCOLOR命令やVARCOLOR命令などによってすでに画面の色が透明ではなく
別の色になっていることを考慮してSPCOLOR OUTで現在の色を取得しているにょ。
「それを言ったらフェードインも黒から透明とは限らないのでは?」という意見もありそう
だけどその場合はフェードインに別途引数を渡す必要があるにょ。
基本的にDEFによる命令や関数は引数を省略した書き方はできないため滅多に使用しない
ような用途のために引数を用意するのはあまり使い勝手が良いとはいえないにょ。
必要になるとすればフェードアウトをする前の色に戻すという場合が大半だろうけど
その場合はグローバル変数にその色情報を入れておく必要があるにょ。
わざわざそのためだけにグローバル変数を定義して云々の注意書きを行う必要があるだけ
ではなくFADEINで自動的に元に戻すためにはFADEOUTを実行時にも元の値を保存するか否かの
オプション設定を行う必要があるけどせっかくシンプルにまとまったプログラムが冗長になる
ためやめたにょ。

またフェードイン、フェードアウトはSPANIMによる自動処理であるためその処理はバック
グラウンドで行われるにょ。
ただし、フェードインとフェードアウトが連続する場合はウェイトを挟まないと正常な
動作ができないにょ。
つまり、FADEIN 300ならばWAIT 300が必要ということにょ。
これは単にFADEIN 300:FADEOUT 300のように連続して書いた場合に誤動作してしまうという
だけなのでそれにさえ注意して使えば問題ないにょ。
SPANIMを使わず段階的に変化するプログラムを自前で用意したり、SPANIM使用時でもDEF内に
WAITを入れたりするとフェードインやフェードアウトが完了するまでは何も行えないにょ。

このフェードイン、フェードアウト命令はそれぞれSPANIMEを使って描画しているのではなく
任意の色から任意の色に変化させるVARCOLOR命令を使っているにょ。
というのもフェードインやフェードアウトは共通部分が多いし、スプライトの初期設定処理を
別途FADEINITなどの命令を作って行うようりも汎用的なVARCOLOR命令を作ってそこで初期化
処理を行う方が短くなるためにょ。
そして、任意の色から任意の色に変化させる汎用命令があればホワイトアウトやレッド
アウトにも対応できるし、それ以外の自由な使い方もできるからね。
ホワイトアウトならばVARCOLOR RGB(0,0,0,0),RGB(255,255,255),300のように透明色から
不透明の白へと変化させればいいだけにょ。

あと変化はさせないけど特定の色に画面全体を変えたいという場合のためにSETCOLOR命令も
用意しているにょ。
これは、SETCOLOR RGB(160,0,64,200)とすれば海中にいるような表現も可能になるにょ。
しかし、この場合は画面の最前面に半透明の青っぽいスプライトがあるためコンソール
文字も青くなってしまい見辛くなるにょ。
コンソールを消さないようにするためにSPOFSでコンソールより後ろに置く必要があるにょ。
これはZ座標を省略した場合コンソール文字はZ座標が0になるためSPOFSで管理番号0の
スプライトのZ座標を1にすればいいだけにょ。
もちろん、その場合は他のスプライトなどがZ座標0以下になればSETCOLORの効果適用外に
なってしまうため自分のプログラムで使用しているZ座標を把握しておく必要があるにょ。
VARCOLOR命令やFADEIN、FADEOUT命令ではDEF内にSPOFSがあるためもしもコンソール文字を
除いてフェードアウトしたいという場合にはVARCOLORのDEF内にあるSPOFSを書き換える
必要があるにょ。
これは画面を覆うスプライトのZ座標を引数で設定できるようにすればプログラムを書き
換えずに対応できるけどそれは上記のように滅多に使わないものに余分な引数を用意したく
ないということで必要な人は各自で対応するといいにょ。


次はSUFFIX()関数について書くにょ。
これは変数の型を取得できる関数で実数型の時は1、整数型の時は-1、文字列の時は0という
値を返すにょ。
この関数が何に使えるかというとDEFで自作関数(命令)を作るときに便利にょ。
というのもDEFではDEF A(B)としたときにはこの時点で変数Bは数値変数か文字列変数かが
確定しないためにょ。
つまり、このSUFFIX()関数があれば引数に文字列と数値のどちらでもOKとなる関数や命令を
作ることができるというわけにょ。(その使用例が下記のBTWAIT命令)

まず、数値と文字列の判別にょ。
これはinfとnanを駆使して判別を行うという方法もあるけど実はプチコン3号(ver.3.1.0)
では、文字列変数への数値の代入はできないけど式の比較演算をした際には「3」という値を
返すにょ。
本来ならプチコン3号の場合は0か1しか返さないのでこれはバグの可能性も高そうだけど
これを使うことで大幅なリスト短縮ができるにょ。
数値か文字列かの判別ができたら数値が整数か実数かの判別にょ。
これは変数Vに0.5を代入して0になるか0.5のままかで分かるにょ。
というわけで、知っていれば簡単に作れるSUFFIX()関数だけど普通に作れば恐らくほとんどの
人が四苦八苦すると思われるにょ。

BTWAIT命令について書くにょ。
これは「Aボタン入力待ち」などのボタン入力待ち状態を書けない初心者のための命令だけど
Aボタン専用では使える範囲が狭いので汎用性を高めているにょ。(専用にして短いリストで
済ませるというのも1つの選択肢ではあるけど今回はせっかく作ったSUFFIX()関数の活用例
としての意味合いもあるため汎用性を高くした)
AボタンとBボタンを両方押すまで待つとかも作れるけどその際にはSUFFIX()関数を用いて
BTWAIT 48 と BTWAIT "AB" のどちらでも動作するようになるにょ。(もちろんリテラル
での指定ではなく数値変数や文字列変数の指定も可能)
文字列で指定した際のBUTTON()関数の値を求めるのがBTNUM()関数にょ。
BTNUM("AB")で48という値を取得できるにょ。(リストが長くなるのでBTNUM()の方は拡張
スライドパッドのZL、ZRには対応していないのでZLやZRを使いたい場合は数値で指定する
必要がある)

このBTWAIT命令のリストを見るとREPEAT〜UNTILが2回使われて冗長に感じるかもしれないけど
これは誤動作防止のためにょ。
Aボタン入力待ちでAWAIT "A"が連続する場合はAボタンを長押ししていたらボタン入力待ちが
有効に働かないため最初のREPEAT〜UNTILでボタンが離されるまで待ち次のREPEAT〜UNTILで
正しく押されるまで待っているにょ。
こんなことをしなくてもBUTTON(2)で解決できると思うかもしれないけど単一ボタンならば
それで良くても複数ボタンの入力待ちは1フレームのずれもなく複数のボタンを入力しなくては
ならないため操作性が非常に悪くなってしまうにょ。
あと本来ならばWAITもしくはVSYNCを入れないと正常動作しないのだけどREPEAT〜UNTILで
離した状態と押した状態の2回入れているためWAITやVSYNCが無くても正常動作が行えるにょ。


これで、私がここ最近にプチコン3号で作った命令や関数についての解説が終わったわけ
だけど多くのものがtwitterやMiiverseで話題として出たものを作ってみただけにょ。
フェードイン、フェードアウトはすでに何人もが同じような処理を行うルーチンを作って
いるけどSPANIMを使えば単純化できるのにと思い今回作ってみたにょ。
「無い物は作る」「あっても作る」(自分でより良いと感じるものができそうならば作る)
というだけなので需要がありそうだからというだけではなく自分で作りたいと思ったから
作っただけにすぎないにょ。
フェードインやフェードアウトはそこそこ使えそうだけどBEEPOFF命令やTIMER()関数などは
使いどころが非常に難しいにょ。
とりあえず欲している人がいたので作ってみたという程度のものなので実用性があるかどうか
という点に関しては疑問があるものであっても使いたい人が使ってくれたらいいと思うにょ。

ちなみにver.3.2.0でも新規命令が増える予定になっているにょ。
ニンドリ5月号を見る限りではフェード系命令とスプライトの加算処理が可能になるっぽいにょ。
今回作ったフェードイン、フェードアウトだけどこれもver.3.2.0が来たら用済みになる
可能性が高いにょ。(ver.3.1.0に搭載された新規命令の大半はすでに似たような動作を
する命令を作っていたので個人的にはありがたみはなかったけど標準で搭載されるという
のは非常に大きな意味を持つので喜ばしいと感じた)
加算処理ができれば現状は乗算しかできず、色を重ねていけばどんどん暗くなる(RGBの
値は0に近づく)けど加算処理ではその逆で色を重ねていけばどんどん明るくなるにょ。
これを使えば発光的な表現も可能になるにょ。
お絵かきソフトであれば乗算だけではなくスクリーン(加算)に対応させることが可能になる
ため表現できる範囲がかなり広がるにょ。
とはいえ、スプライト用GRPは1枚しかないため400x240だと2枚しか確保できないのが難点
だけどね。
キャンバスサイズを256x240にすればレイヤーが4枚が使用でき各レイヤーで不透明度や
乗算、スクリーンが可能になるにょ。(不透明度や乗算やスクリーンをレイヤーごとに
設定しなければスプライト用GRP以外でも問題ないのでレイヤーを10枚以上にすることも
可能だけど)




掲示板管理者へ連絡 無料レンタル掲示板