LWのサイゼリヤ

ミラノ風ドリア300円

5/18 void Animation.Fire()みたいなやつ

・お題箱10

17.前半の話が自明じゃない人間(大人)は存在するのか!?
それはともかく、たとえば手塚漫画とかのステレオタイプな黒人キャラが姿を消したように、ひなこのーとは(実在しうる障碍者の表現を取ってるので)世の中がこのまま進めば存在できなくなりそうだよねという話題のつもりだったんだけど、まあおもしろさとは別問題(むしろ反比例)という理屈は理解できるので特にいうことはないです
(俺は見ている最中に気になってしまうので避けて欲しいと思うけど閾値の問題だしね)

前回のお題の主旨がわかりました。言う通り、まあ程度問題ではありますね。
それを踏まえて僕の程度の感じ方としては、ひなこのーとのキャラの挙動は確かに障碍的ではありますが、通常の日常系アニメの障碍度合いと地続きなのでそこまで気にならないです。裏を返すと、日常系アニメには多かれ少なかれ障碍者はだいたい常に存在していて、ひなこのーとは比較的それが強く出ているアニメというくらいの認識です。
関連する話題として、最近ゆうきゆうがそんなことをツイートしているのを発見しました。

(漫画はここから読めます→
これはスーパーひなこのーとということになりますが、ここまで行くとゆうきゆうに言われなくても気になってくるレベルではあります(それでもポリティカルコレクトネスと結び付けて考えるほどには(お題箱への質問が無ければ)気にならなかったと思いますが)。

18.沖縄の基地問題についてどう思われますか?

どう。どう思うかって、難しいですね。何も思いません。
正確に言うと、興味がないためにいま何も思わないという現状と、仮に頑張って実情を調べたとしても(この仮定が相当に無謀なのですが)恐らく何も思わないであろうという可能性の二つをコミで何も思いません。
真実であるという前提を抜きにして何か虚構的なストーリーが提示されれば「気の毒だなあ」くらいのことは言える可能性もありますが、それが限界でしょう。

19.男主人公ってなんでダメなんでしたっけ

容姿が可愛くないからです。
僕は可愛くないキャラは可愛くないというだけの理由で萌えコンテンツから排除するのに十分と考える派閥です。ヒロインの魅力を引き出すためには男主人公が必要な派閥があるのは理解しますが、僕はその派閥ではありません。
誤解を招かないように一応言うと、「純粋な萌えファクターとしては男性主人公は不要」という前置き付きの話です。他のファクターと複合した結果男性主人公が必要とされることに納得できる場合や、そもそも最初から萌えコンテンツではない場合などは一向に構いません。

・自動音楽生成マシーン

C++で作った。
挙動は見ればわかると思うんだけど、具体的な説明をするとネタバレになるから主旨の解説ができない。
2017-05-18_224849
内容は大したことないけど、アニメーションの再生について個人的に学ぶところがあったのでメモがてら書いておく。

補足23:最初はいつも通り誰でも読めるように書こうと思ったけど、プログラムの概念から説明するのはあまりにも大変だったので諦めてしまった。
とはいえ俺もプログラミングに関しては「入門書を読んだことがある」程度のスキルしかないので、せいぜい「プログラムとは命令の列である」くらいのことを知っていれば読めると思う。


アニメーションというのは、上のプログラムではセルの誕生時に白いものがせり出してきたり死亡時に白いやつが段々小さくなっていくやつのことだ。しかし、これでは説明しにくいし想像もしにくいだろうから、アクションゲームで攻撃ボタンを押したときに火を吐いたり氷を吹いたりするアニメーションを思い浮かべた方がいい。
今回使ったDXライブラリにはアニメーションを実行するための関数は用意されていないので、例えば「炎属性のキャラが5秒間火を吐く」アニメーションをやりたい場合、「時間変化を内蔵した火吐き関数→Fire()」を5秒間実行し続けなければならない。
すりゃいいじゃんという話なのだが、問題が一つあって、アニメーションはいつどこでいくつ発生するのかプログラムの中からはわからない。炎属性のキャラが攻撃する間に氷属性のキャラが攻撃する(氷吹き関数→Ice())かもしれないし、Fire()が完全に終わる前に(火の粉の最後の一つが消えてしまうよりも前に)炎属性のキャラは再びFire()するかもしれない。
攻撃時間がそれぞれある程度持続するとき、ある瞬間にはFire()二つとIce()一つが同時に発生するということが起こってくる。これらを実行するにはメインループ内で「Fire()→Fire()→Ice()」という命令列を作るしかないのだが、当然プログラムの実行中に命令列を書き換えることはできないので、実際には分岐を活用してこうした命令列を動的に作成することになる。

俺はこのやり方がよくわからなかった。
メインループ内にあらかじめFire()やIce()をたくさん書いておいてFlagでActive状態を管理するというのが一番素直なやり方だが、このやり方ではFlag管理が煩雑になりすぎるし、何より一度に実行できるアニメーションの数に上限ができてしまう。
というのは、Flagで出来るのはActive/InActiveの切り替えでしかないので、Fire()実行中にもう一つのFire()を出すことはできない。実際のゲーム上では一つの火吹き攻撃が終わるまで次の火吹きはできないということになってしまい、あまりスマートではない(二つFire()を書いておけば二つまでは出すことができるが、上限があるという問題は解決していないし、プログラムがかなり醜くなる)。

アニメーション管理クラスAnimationを作成してメンバ変数にFireFlagやIceFlag、メンバ関数にFire()やIce()を組み込めばいいのではないかとも考えた。これで管理はだいぶしやすくなったのだが、依然として全長が動的に可変という条件で命令列を作るやり方がわからなかった。配列にAnimationのインスタンスを詰めて毎ループごとに全て走査するというのをやってみたが、配列は固定長なので、アニメーション数が有限であるという根本的な問題は解決していない。

色々考えた末、今やりたいのが動的なメモリ確保と管理であることに気付き、じゃあリスト構造を使えばいいのかとわかった。
最終的に、以下のシステムなら要求を満たしてアニメーションを実行できることがわかった。
まず、

1.先述したようなアニメーション管理クラスAnimation
2.Animationのリスト構造(headの名前で識別したので、このリストのことはAnimationHeadリストとでも呼ぶ)

を作り、比較的グローバルな場所に置く。
メインループ内でアニメーションが発生した時点で、適切な初期値を与えたAnimationインスタンスを作成してAnimationHeadリストに追加する。AnimationHeadを実際に扱う関数Animate()は別に存在し、AnimationHeadリストの頭から尻までを毎ループごとに走査し、各インスタンスの主張するアニメを常に実行する。また、Animationインスタンスは自身の行うべきアニメが終了した時点(Fire()の例なら5秒経過後)で返り値でそれを示し、返り値を受け取ったAnimate()は終了したAnimationをリストから削除することで実行から終了までが完了する。これによって無制限にAnimationを設定・実行・終了できるようになる(本当は無制限ではなくてメモリ上限があるんだけど、どうせ上限行かないだろと思って作ってない)。

リスト構造っていつ使うのかよくわからなかったけど、こういうとき使うのか~とわかって勉強になった(C++だしvectorとか使った方がいい感じにできるのかもしれないけど、初心者だからチート使うより基本を押さえた方が教育的だなと思って使わなかった)。
jBHsA8aa[1]
あと俺は印刷しないとプログラムを読めないんだけどこれは慣れの問題か?
画面上だとモニターの範囲しか一度に目を通せないから定義にいちいち飛んだり参照したりしないといけなくて集中できない(紙だとバーッと広げて全域を見渡せるので見渡しがいい)。