先週日記書いてたのに上げるの忘れてた。
iPod nanoは整備品が一番安かったのでそれで。といっても1万5千円近くはした。いたいいたい。第4世代だったのが第5世代になったのでちょっとパワーアップだよ!そんなに嬉しい機能無いけど。
土曜日は昼過ぎから頭痛がして買い物にも行けず寝てただけ。夜になって少し良くなったんだが暑すぎただけだったんだろうか。
日曜は大丈夫だったんだけど調子に乗ってまた頭痛くなっても嫌だからごろごろしてた。選挙と買い物行ったくらいだった。
急いでゲーム作らないといけないはずなんだが大丈夫なんだろうか俺は…。
同期スクロールでっちあげ完了。
33ms毎に
というのを繰りかえした。
Durationプロパティを設定しとけばそこまでしか再生しないで止まってくれる。 Beginでアニメーションを開始するがBeginするとStoryboardの内部時刻は最初にリセットされちゃう。 そこでSeekAlignedToLastTickで再生開始して欲しい時刻までぶっとばす。
こんな感じでいけました。33msなのは30fps動作させてるからなんで、違うフレームレートで動かしたければ変えればよい。
BeginしてないとSeekAlignedToLastTickが効かないのと、Beginすると最初から再生開始なのと*1、SeekじゃなくてSeekAlignedToLastTickを使わないといけないのがポイント。本当のポイントはDurationの設定だが。
とりあえずこれで同期再生できたので良かった。厳密には同期してないんだがこまけぇこまけぇ。
あとはアニメーションしてるこいつにVisualTreeHelperクラスを使って衝突判定をしてやる。点で衝突判定と矩形で衝突判定ができるけど、とりあえず今回は点で衝突判定してやる。
これは何事もなく出来るんだけど、きっかり見た目で衝突判定するので気をつけたい。
しかしこの判定が怪しい。
描画はWriteableBitmapに対してやってて、
##highlight ruby #@bitmapはWriteableBitmap、@stageはXAMLから読んできた背景用データ @bitmap.render(@stage, transform)
のtransformの部分に、上手い位置に表示されるように平行移動分を入れてるわけよ。
そうすると@stage自体はその平行移動分を知らないはず。知ってたとしても一時的なものだよね?
でもVisualTreeHelperの衝突判定をすると、その移動分をどこにも渡していないのにちゃんと反映されて衝突判定されてしまうのだ…!なにそれこわーい。
まあ見た目通りの判定をしたいからべつにいいというか望むところなんだが大丈夫かなこれ…?いつか修正されるかもしれないのがこわいね。
話はとぶけど、毎フレームの更新。今までDispatcherTimerに最速を設定してTickイベントで33ms経過してたら更新ってしてたんだけど、アニメーションのドキュメント読んでたらフレームアニメーションを作るならCompositionTarget.Renderingイベントを使えっていう記事があった。
これなら描画タイミングでイベントをよんでくれるのでだいたい60fpsで実行できるようだ。明らかにタイマーを最速でぶんまわすよりまともなのでこれにしよう。
ちなみにDispatcherTimerで33ms毎にイベント起こしてもらうのは精度悪すぎて無理。本来そんな用途に使うものじゃないね。
DispatcherTimerじゃない普通のTimerは別スレッドでイベント起こしてくれるんだが、UIにはメインスレッドからしか触れないので少なくとも描画更新が無理。別スレッドだとpも使えなくて地獄だぜー。
あとはもうSilverlightっぽいところは終わりでゲームの中身制作になっていくかなー。こっからが本番なんだけどめんどくせーんだよな。
*1 PauseとResume使えってことかね