電気通信大学 X68000同好会 酒井利治氏作 アクションパズル「φ(ファイ)」のデモデータを動かすスクリーンセーバーです。 ゲームの方は、こちら(win版)をご覧下さい。
phisvr.lzh(32.2 kBYTE) [/2006-04-22]
ただしphisvr.lzhには、実行に必要な画像ファイルとデモデータが入っていません。 ゲームに同梱されているので、そちらもダウンロードして下さい。
windows版φ(phiWin)にはデモを流す機能があるんですが、このデモを眺めてる内に スクリーンセーバーが働いて邪魔だなぁと思ったのが 今回の製作のきっかけです。いっそのこと、スクリーンセーバーにしてしまえ、と。
スクリーンセーバーなんて全然作ったことが無かったので、まずウェブを検索しました。
作り方を解説してるページもあるにはあったんですが、VBで作る方法や
VC++でもSDKを使う方法が多かったです。
しかしphiWinはMFCを使っていたため、SDKに直すのは労力がかかりすぎて嫌でした。
そこで、VC++のスクリーンセーバーのサンプルであるsaverを改造することにしました。
phiWinは比較的素直にMFCを使っているため、
CViewの派生クラスのOnDraw()によって描画しています。
しかしsaverはタイマー割り込みの中でデバイスコンテキストを取得し、直接描画していました。
phiWinは割り込み内でInvalidate()を使って間接的にOnDraw()を呼んでいたので、
そこはsaverに倣って直しました。
そして、タイマー割り込みの方法をWM_TIMERイベント一本にしました。
phiWinではどちらかというとマルチメディアタイマー(timeSetEvent)を使っていたのですが、
その割り込みではOnDraw()が処理されるのを待つようにしていたため、
OnDraw()を使わなくなったことに対応するのが面倒だったことと、
そもそもtimeSetEvent()は精度が高い代わりにメッセージループが正常に回らなくなるという
大きな弊害があったことが主な理由です。
スクリーンセーバー実行中に固まると大変ですからねー。
さて、そこまでは比較的簡単に出来たんですが、困ったのがエラー処理です。
デモデータが見つからない時に、その旨をMessageBoxで表示してから終了するようにした
つもりなんですが、MessageBoxが表示されるけれど、フォーカスが当たらない。
しかもマウスを動かすだけで終了してしまう。
マウスを動かすと終了してしまうのは、WM_MOUSEMOVEメッセージが来たら終了するように
なってたからだとすぐ分かったので、エラーの場合は終了しないように変えました。
WM_KEYDOWNとかWM_SYSKEYDOWNとかWM_LBUTTONDOWNとかも、軒並み同じです。
で、フォーカスが当たらないのは、同様にOnNcActivate()の中でreturn FALSE
している部分のせいでした。NC系のイベントは全然知らなかったので、
自分では手を入れていなかったのです。くそー、これが無けりゃ
3日は早く完成したのに。
もうひとつ、よく分からなかったのが、「設定」の仕方。
「画面のプロパティ」から「スクリーンセーバー」タブを選ぶと「設定」ボタンがあります。
設定用のダイアログは作ってあるし、phisvr.scrを右クリックして出てくる「設定」メニューでは
ちゃんと設定ダイアログが表示されるのに、「設定」ボタンでは何も起きない。
さんざん調べた結果、起動時オプションの判定用サブルーチンであるMatchOption()が
ショボイせいだという事が分かりました。
しょぼいというか、古いのかな?
「/c」というオプションが指定された時に設定ダイアログを表示するようになってるんですが、
実際は「/c:数値」という形でオプションが渡ってきていて、MatchOption()では
別物だと判定されてしまったのです。数値の意味は分からなかったので、
「:」以降は無視することにしましたが、それで動いているようです。
それにしても、saverの構成はおもしろいです。
CWndの派生クラスのCDrawWndで描画とタイマーを処理。
実際にスクリーンセーバーとして動くときには、CDrawWndから派生したCSaverWndで
マウスやキーのイベントを処理。
サンプルとして表示するときはCDrawWndだけ使うので、
フラグなんかを使ってイベントを処理したりしなかったりといった格好の悪いことを
しなくて済む。
というか、これがオブジェクト指向の考え方なんでしょうねぇ。
しかし、スクリーンセーバーの事を全く知らずによくここまで出来たもんです。
動きが遅いのが難点だけど、サンプルのsaverも同じような速度だし、仕方ないか。
2002-04-12 | タイマー割り込み内から直接ゲーム処理をしていたが、メッセージを投げて処理するよう変更。 セットアップ時にクリアすると固まるバグを修正。 |
2002-04-21 | メッセージを投げるタイミングを、OnIdle()に変更。 |
2003-02-16 | ビットマップリソース(HDIB)の解放処理を追加(汗) |
2005-12-17 | OnIdle()の中でウェイトするよう修正。 |
2005-12-23 | 横スクロールする文字を入れてみた。設定ダイアログから変更可能。 |
2006-04-22 | ドキュメントをちょっと修正。 |